efae2487974181dee4411f47d591c2c896a1a1e1
[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.17 2006/12/20 18:14:34 dillon 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) printf("%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                 printf("%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                         printf("%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                         printf("%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                         printf("%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                         printf("%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                                 printf("%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                                 printf("%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                                 printf("%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                         printf("%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                 printf("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 (!cold)
877                 scsi_low_rescan_bus_cam(slp);
878         return 0;
879 }
880
881 static int
882 scsi_low_dettach_cam(struct scsi_low_softc *slp)
883 {
884         xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
885         xpt_free_path(slp->sl_si.path);
886         xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
887         cam_sim_free(slp->sl_si.sim);
888         slp->sl_si.sim = NULL;
889         return 0;
890 }
891
892 static int
893 scsi_low_ccb_setup_cam(struct scsi_low_softc *slp, struct slccb *cb)
894 {
895         union ccb *ccb = (union ccb *) cb->osdep;
896
897         if ((cb->ccb_flags & CCB_SCSIIO) != 0)
898         {
899                 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
900                 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
901                 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
902                 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
903                 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
904                         cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
905                 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
906                         cb->ccb_scp.scp_direction = SCSI_LOW_READ;
907                 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
908         }
909         else
910         {
911                 scsi_low_unit_ready_cmd(cb);
912         }
913         return SCSI_LOW_START_QTAG;
914 }
915
916 static int
917 scsi_low_done_cam(struct scsi_low_softc *slp, struct slccb *cb)
918 {
919         union ccb *ccb;
920
921         ccb = (union ccb *) cb->osdep;
922         if (cb->ccb_error == 0)
923         {
924                 ccb->ccb_h.status = CAM_REQ_CMP;
925                 ccb->csio.resid = 0;
926         }
927         else    
928         {
929                 if (cb->ccb_rcnt >= slp->sl_max_retry)
930                         cb->ccb_error |= ABORTIO;
931
932                 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
933                     (cb->ccb_error & ABORTIO) == 0)
934                         return EJUSTRETURN;
935
936                 if ((cb->ccb_error & SENSEIO) != 0)
937                 {
938                         memcpy(&ccb->csio.sense_data,
939                                &cb->ccb_sense,
940                                sizeof(ccb->csio.sense_data));
941                 }
942
943                 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
944                                         &scsi_low_error_code_cam[0]);
945         
946 #ifdef  SCSI_LOW_DIAGNOSTIC
947                 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
948                     cb->ccb_scp.scp_cmdlen > 0 &&
949                     (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
950                      SCSI_LOW_CMD_ABORT_WARNING) != 0)
951                 {
952                         printf("%s: WARNING: scsi_low IO abort\n",
953                                 slp->sl_xname);
954                         scsi_low_print(slp, NULL);
955                 }
956 #endif  /* SCSI_LOW_DIAGNOSTIC */
957         }
958
959         if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
960                 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
961
962         if (cb->ccb_scp.scp_status == ST_UNKNOWN)
963                 ccb->csio.scsi_status = 0;      /* XXX */
964         else
965                 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
966
967         if ((cb->ccb_flags & CCB_NOSDONE) == 0)
968                 xpt_done(ccb);
969         return 0;
970 }
971
972 static void
973 scsi_low_timeout_cam(struct scsi_low_softc *slp, int ch, int action)
974 {
975         switch (ch)
976         {
977         case SCSI_LOW_TIMEOUT_CH_IO:
978                 switch (action)
979                 {
980                 case SCSI_LOW_TIMEOUT_START:
981                         callout_reset(&slp->sl_si.timeout_ch,
982                             hz / SCSI_LOW_TIMEOUT_HZ, scsi_low_timeout, slp);
983                         break;
984                 case SCSI_LOW_TIMEOUT_STOP:
985                         callout_stop(&slp->sl_si.timeout_ch);
986                         break;
987                 }
988                 break;
989
990         case SCSI_LOW_TIMEOUT_CH_ENGAGE:
991                 switch (action)
992                 {
993                 case SCSI_LOW_TIMEOUT_START:
994                         callout_reset(&slp->sl_si.engage_ch, 1,
995                                       scsi_low_engage, slp);
996                         break;
997                 case SCSI_LOW_TIMEOUT_STOP:
998                         callout_stop(&slp->sl_si.engage_ch);
999                         break;
1000                 }
1001                 break;
1002         case SCSI_LOW_TIMEOUT_CH_RECOVER:
1003                 break;
1004         }
1005 }
1006
1007 /**************************************************************
1008  * scsi low deactivate and activate
1009  **************************************************************/
1010 int
1011 scsi_low_is_busy(struct scsi_low_softc *slp)
1012 {
1013         if (slp->sl_nio > 0)
1014                 return EBUSY;
1015         return 0;
1016 }
1017
1018 int
1019 scsi_low_deactivate(struct scsi_low_softc *slp)
1020 {
1021         crit_enter();
1022         slp->sl_flags |= HW_INACTIVE;
1023         (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1024                 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1025         (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1026                 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1027         crit_exit();
1028         return 0;
1029 }
1030
1031 int
1032 scsi_low_activate(struct scsi_low_softc *slp)
1033 {
1034         int error;
1035
1036         crit_enter();
1037         slp->sl_flags &= ~HW_INACTIVE;
1038         if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1039         {
1040                 slp->sl_flags |= HW_INACTIVE;
1041                 crit_exit();
1042                 return error;
1043         }
1044
1045         slp->sl_timeout_count = 0;
1046         (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1047                 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1048         crit_exit();
1049         return 0;
1050 }
1051
1052 /**************************************************************
1053  * scsi low log
1054  **************************************************************/
1055 #ifdef  SCSI_LOW_DIAGNOSTIC
1056 static void scsi_low_msg_log_init (struct scsi_low_msg_log *);
1057 static void scsi_low_msg_log_write (struct scsi_low_msg_log *, u_int8_t *,
1058 int);
1059 static void scsi_low_msg_log_show (struct scsi_low_msg_log *, char *, int);
1060
1061 static void
1062 scsi_low_msg_log_init(struct scsi_low_msg_log *slmlp)
1063 {
1064         slmlp->slml_ptr = 0;
1065 }
1066
1067 static void
1068 scsi_low_msg_log_write(struct scsi_low_msg_log *slmlp, u_int8_t *datap, int len)
1069 {
1070         int ptr, ind;
1071
1072         if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1073                 return;
1074
1075         ptr = slmlp->slml_ptr ++;
1076         for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1077                 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1078         for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1079                 slmlp->slml_msg[ptr].msg[ind] = 0;
1080 }
1081         
1082 static void
1083 scsi_low_msg_log_show(struct scsi_low_msg_log *slmlp, char *s, int len)
1084 {
1085         int ptr, ind;
1086
1087         printf("%s: (%d) ", s, slmlp->slml_ptr);
1088         for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1089         {
1090                 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1091                      ind ++)
1092                 {
1093                         printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1094                 }
1095                 printf(">");
1096         }
1097         printf("\n");
1098 }
1099 #endif  /* SCSI_LOW_DIAGNOSTIC */
1100
1101 /**************************************************************
1102  * power control
1103  **************************************************************/
1104 static void
1105 scsi_low_engage(void *arg)
1106 {
1107         struct scsi_low_softc *slp = arg;
1108
1109         crit_enter();
1110
1111         switch (slp->sl_rstep)
1112         {
1113         case 0:
1114                 slp->sl_rstep ++;
1115                 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1116                 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 
1117                         SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1118                 break;
1119
1120         case 1:
1121                 slp->sl_rstep ++;
1122                 slp->sl_flags &= ~HW_RESUME;
1123                 scsi_low_start(slp);
1124                 break;
1125
1126         case 2:
1127                 break;
1128         }
1129         crit_exit();
1130 }
1131
1132 static int
1133 scsi_low_init(struct scsi_low_softc *slp, u_int flags)
1134 {
1135         int rv = 0;
1136
1137         slp->sl_flags |= HW_INITIALIZING;
1138
1139         /* clear power control timeout */
1140         if ((slp->sl_flags & HW_POWERCTRL) != 0)
1141         {
1142                 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 
1143                         SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1144                 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1145                 slp->sl_active = 1;
1146                 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1147         }
1148
1149         /* reset current nexus */
1150         scsi_low_reset_nexus(slp, flags);
1151         if ((slp->sl_flags & HW_INACTIVE) != 0)
1152         {
1153                 rv = EBUSY;
1154                 goto out;
1155         }
1156
1157         if (flags != SCSI_LOW_RESTART_SOFT)
1158         {
1159                 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1160         }
1161
1162 out:
1163         slp->sl_flags &= ~HW_INITIALIZING;
1164         return rv;
1165 }
1166
1167 /**************************************************************
1168  * allocate lun_info
1169  **************************************************************/
1170 static struct lun_info *
1171 scsi_low_alloc_li(struct targ_info *ti, int lun, int alloc)
1172 {
1173         struct scsi_low_softc *slp = ti->ti_sc;
1174         struct lun_info *li;
1175
1176         li = LIST_FIRST(&ti->ti_litab); 
1177         if (li != NULL)
1178         { 
1179                 if (li->li_lun == lun)
1180                         return li;
1181
1182                 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1183                 {
1184                         if (li->li_lun == lun)
1185                         {
1186                                 LIST_REMOVE(li, lun_chain);
1187                                 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1188                                 return li;
1189                         }
1190                 }
1191         }
1192
1193         if (alloc == 0)
1194                 return li;
1195
1196         li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1197         if (li == NULL)
1198                 panic("no lun info mem");
1199
1200         SCSI_LOW_BZERO(li, ti->ti_lunsize);
1201         li->li_lun = lun;
1202         li->li_ti = ti;
1203
1204         li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1205                           SCSI_LOW_QTAG;
1206         li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1207         li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1208 #ifdef  SCSI_LOW_FLAGS_QUIRKS_OK
1209         li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1210 #endif  /* SCSI_LOW_FLAGS_QUIRKS_OK */
1211
1212         li->li_qtagbits = (u_int) -1;
1213
1214         TAILQ_INIT(&li->li_discq);
1215         LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1216
1217         /* host specific structure initialization per lun */
1218         if (slp->sl_funcs->scsi_low_lun_init != NULL)
1219                 (*slp->sl_funcs->scsi_low_lun_init)
1220                         (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1221         scsi_low_calcf_lun(li);
1222         return li;
1223 }
1224
1225 /**************************************************************
1226  * allocate targ_info
1227  **************************************************************/
1228 static struct targ_info *
1229 scsi_low_alloc_ti(struct scsi_low_softc *slp, int targ)
1230 {
1231         struct targ_info *ti;
1232
1233         if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1234                 TAILQ_INIT(&slp->sl_titab);
1235
1236         ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1237         if (ti == NULL)
1238                 panic("%s short of memory", slp->sl_xname);
1239
1240         SCSI_LOW_BZERO(ti, slp->sl_targsize);
1241         ti->ti_id = targ;
1242         ti->ti_sc = slp;
1243
1244         slp->sl_ti[targ] = ti;
1245         TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1246         LIST_INIT(&ti->ti_litab);
1247
1248         ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1249         ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1250         ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1251 #ifdef  SCSI_LOW_FLAGS_QUIRKS_OK
1252         ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1253 #endif  /* SCSI_LOW_FLAGS_QUIRKS_OK */
1254
1255         if (slp->sl_funcs->scsi_low_targ_init != NULL)
1256         {
1257                 (*slp->sl_funcs->scsi_low_targ_init)
1258                         (slp, ti, SCSI_LOW_INFO_ALLOC);
1259         }
1260         scsi_low_calcf_target(ti);
1261         return ti;
1262 }
1263
1264 static void
1265 scsi_low_free_ti(struct scsi_low_softc *slp)
1266 {
1267         struct targ_info *ti, *tib;
1268         struct lun_info *li, *nli;
1269
1270         for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1271         {
1272                 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1273                 {
1274                         if (slp->sl_funcs->scsi_low_lun_init != NULL)
1275                         {
1276                                 (*slp->sl_funcs->scsi_low_lun_init)
1277                                         (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1278                         }
1279                         nli = LIST_NEXT(li, lun_chain);
1280                         SCSI_LOW_FREE(li);
1281                 }
1282
1283                 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1284                 {
1285                         (*slp->sl_funcs->scsi_low_targ_init)
1286                                 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1287                 }
1288                 tib = TAILQ_NEXT(ti, ti_chain);
1289                 SCSI_LOW_FREE(ti);
1290         }
1291 }
1292
1293 /**************************************************************
1294  * timeout
1295  **************************************************************/
1296 void
1297 scsi_low_bus_idle(struct scsi_low_softc *slp)
1298 {
1299         slp->sl_retry_sel = 0;
1300         if (slp->sl_Tnexus == NULL)
1301                 scsi_low_start(slp);
1302 }
1303
1304 static void
1305 scsi_low_timeout(void *arg)
1306 {
1307         struct scsi_low_softc *slp = arg;
1308
1309         crit_enter();
1310         scsi_low_timeout_check(slp);
1311         (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1312                 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1313         crit_exit();
1314 }
1315
1316 static int
1317 scsi_low_timeout_check(struct scsi_low_softc *slp)
1318 {
1319         struct targ_info *ti;
1320         struct lun_info *li;
1321         struct slccb *cb = NULL;                /* XXX */
1322
1323         /* selection restart */
1324         if (slp->sl_retry_sel != 0)
1325         {
1326                 slp->sl_retry_sel = 0;
1327                 if (slp->sl_Tnexus != NULL)
1328                         goto step1;
1329
1330                 cb = TAILQ_FIRST(&slp->sl_start);
1331                 if (cb == NULL)
1332                         goto step1;
1333
1334                 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1335                 {
1336                         cb->ccb_flags |= CCB_NORETRY;
1337                         cb->ccb_error |= SELTIMEOUTIO;
1338                         if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1339                                 panic("%s: ccb not finished", slp->sl_xname);
1340                 }
1341
1342                 if (slp->sl_Tnexus == NULL)
1343                         scsi_low_start(slp);
1344         }
1345
1346         /* call hardware timeout */
1347 step1:
1348         if (slp->sl_funcs->scsi_low_timeout != NULL)
1349         {
1350                 (*slp->sl_funcs->scsi_low_timeout) (slp);
1351         }
1352         
1353         if (slp->sl_timeout_count ++ < 
1354             SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1355                 return 0;
1356
1357         slp->sl_timeout_count = 0;
1358         if (slp->sl_nio > 0)
1359         {
1360                 if ((cb = slp->sl_Qnexus) != NULL)
1361                 {
1362                         cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1363                         if (cb->ccb_tc < 0)
1364                                 goto bus_reset;
1365                 }
1366                 else if (slp->sl_disc == 0)
1367                 {
1368                         if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1369                                 return 0;
1370
1371                         cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1372                         if (cb->ccb_tc < 0)
1373                                 goto bus_reset;
1374                 }
1375                 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1376                           ti = TAILQ_NEXT(ti, ti_chain))
1377                 {
1378                         if (ti->ti_disc == 0)
1379                                 continue;
1380
1381                         for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1382                              li = LIST_NEXT(li, lun_chain))
1383                         {
1384                                 for (cb = TAILQ_FIRST(&li->li_discq); 
1385                                      cb != NULL;
1386                                      cb = TAILQ_NEXT(cb, ccb_chain))
1387                                 {
1388                                         cb->ccb_tc -=
1389                                                 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1390                                         if (cb->ccb_tc < 0)
1391                                                 goto bus_reset;
1392                                 }
1393                         }
1394                 }
1395
1396         }
1397         else if ((slp->sl_flags & HW_POWERCTRL) != 0)
1398         {
1399                 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
1400                         return 0;
1401
1402                 if (slp->sl_active != 0)
1403                 {
1404                         slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1405                         slp->sl_active = 0;
1406                         return 0;
1407                 }
1408
1409                 slp->sl_powc --;
1410                 if (slp->sl_powc < 0)
1411                 {
1412                         slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1413                         slp->sl_flags |= HW_POWDOWN;
1414                         (*slp->sl_funcs->scsi_low_power)
1415                                         (slp, SCSI_LOW_POWDOWN);
1416                 }
1417         }
1418         return 0;
1419
1420 bus_reset:
1421         cb->ccb_error |= TIMEOUTIO;
1422         printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
1423         scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
1424         scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
1425         scsi_low_start(slp);
1426         return ERESTART;
1427 }
1428
1429
1430 static int
1431 scsi_low_abort_ccb(struct scsi_low_softc *slp, struct slccb *cb)
1432 {
1433         struct targ_info *ti;
1434         struct lun_info *li;
1435         u_int msg;
1436
1437         if (cb == NULL)
1438                 return EINVAL;
1439         if ((cb->ccb_omsgoutflag & 
1440              (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
1441                 return EBUSY;
1442
1443         ti = cb->ti;
1444         li = cb->li;
1445         if (cb->ccb_tag == SCSI_LOW_UNKTAG)
1446                 msg = SCSI_LOW_MSG_ABORT;
1447         else
1448                 msg = SCSI_LOW_MSG_ABORT_QTAG;
1449
1450         cb->ccb_error |= ABORTIO;
1451         cb->ccb_flags |= CCB_NORETRY;
1452         scsi_low_ccb_message_assert(cb, msg);
1453
1454         if (cb == slp->sl_Qnexus)
1455         {
1456                 scsi_low_assert_msg(slp, ti, msg, 1);
1457         }
1458         else if ((cb->ccb_flags & CCB_DISCQ) != 0)
1459         {
1460                 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
1461                         panic("%s: revoked ccb done", slp->sl_xname);
1462
1463                 cb->ccb_flags |= CCB_STARTQ;
1464                 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1465
1466                 if (slp->sl_Tnexus == NULL)
1467                         scsi_low_start(slp);
1468         }
1469         else
1470         {
1471                 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1472                         panic("%s: revoked ccb retried", slp->sl_xname);
1473         }
1474         return 0;
1475 }
1476
1477 /**************************************************************
1478  * Generic SCSI INTERFACE
1479  **************************************************************/
1480 int
1481 scsi_low_attach(struct scsi_low_softc *slp, int openings, int ntargs, int nluns,
1482                 int targsize, int lunsize)
1483 {
1484         struct targ_info *ti;
1485         struct lun_info *li;
1486         int i, nccb, rv;
1487
1488         slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
1489
1490         if (slp->sl_osdep_fp == NULL)
1491                 panic("scsi_low: interface not spcified");
1492
1493         if (ntargs > SCSI_LOW_NTARGETS)
1494         {
1495                 printf("scsi_low: %d targets are too large\n", ntargs);
1496                 printf("change kernel options SCSI_LOW_NTARGETS");
1497                 return EINVAL;
1498         }
1499
1500         if (openings <= 0)
1501                 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
1502         else
1503                 slp->sl_openings = openings;
1504         slp->sl_ntargs = ntargs;
1505         slp->sl_nluns = nluns;
1506         slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
1507
1508         if (lunsize < sizeof(struct lun_info))
1509                 lunsize = sizeof(struct lun_info);
1510
1511         if (targsize < sizeof(struct targ_info))
1512                 targsize = sizeof(struct targ_info);
1513
1514         slp->sl_targsize = targsize;
1515         for (i = 0; i < ntargs; i ++)
1516         {
1517                 ti = scsi_low_alloc_ti(slp, i);
1518                 ti->ti_lunsize = lunsize;
1519                 li = scsi_low_alloc_li(ti, 0, 1);
1520         }
1521
1522         /* initialize queue */
1523         nccb = openings * ntargs;
1524         if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
1525                 nccb = SCSI_LOW_NCCB;
1526         scsi_low_init_ccbque(nccb);
1527         TAILQ_INIT(&slp->sl_start);
1528
1529         /* call os depend attach */
1530         callout_init(&slp->sl_si.timeout_ch);
1531         callout_init(&slp->sl_si.engage_ch);
1532
1533         crit_enter();
1534         rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
1535         if (rv != 0)
1536         {
1537                 crit_exit();
1538                 printf("%s: scsi_low_attach: osdep attach failed\n",
1539                         slp->sl_xname);
1540                 return EINVAL;
1541         }
1542
1543         /* check hardware */
1544         SCSI_LOW_DELAY(1000);   /* wait for 1ms */
1545         if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
1546         {
1547                 crit_exit();
1548                 printf("%s: scsi_low_attach: initialization failed\n",
1549                         slp->sl_xname);
1550                 return EINVAL;
1551         }
1552
1553         /* start watch dog */
1554         slp->sl_timeout_count = 0;
1555         (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1556                  (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1557         LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
1558
1559         /* fake call */
1560         scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
1561
1562 #ifdef  SCSI_LOW_START_UP_CHECK
1563         /* probing devices */
1564         scsi_low_start_up(slp);
1565 #endif  /* SCSI_LOW_START_UP_CHECK */
1566
1567         /* call os depend attach done*/
1568         (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
1569         crit_exit();
1570         return 0;
1571 }
1572
1573 int
1574 scsi_low_dettach(struct scsi_low_softc *slp)
1575 {
1576         int rv;
1577
1578         crit_enter();
1579         if (scsi_low_is_busy(slp) != 0)
1580         {
1581                 crit_exit();
1582                 return EBUSY;
1583         }
1584
1585         scsi_low_deactivate(slp);
1586
1587         rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
1588         if (rv != 0)
1589         {
1590                 crit_exit();
1591                 return EBUSY;
1592         }
1593
1594         scsi_low_free_ti(slp);
1595         LIST_REMOVE(slp, sl_chain);
1596         crit_exit();
1597         return 0;
1598 }
1599
1600 /**************************************************************
1601  * Generic enqueue
1602  **************************************************************/
1603 static int
1604 scsi_low_enqueue(struct scsi_low_softc *slp, struct targ_info *ti,
1605                  struct lun_info *li, struct slccb *cb, u_int flags,
1606                  u_int msg)
1607 {       
1608
1609         cb->ti = ti;
1610         cb->li = li;
1611
1612         scsi_low_ccb_message_assert(cb, msg);
1613
1614         cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
1615         scsi_low_alloc_qtag(cb);
1616
1617         cb->ccb_flags = flags | CCB_STARTQ;
1618         cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1619         cb->ccb_error |= PENDINGIO;
1620
1621         if ((flags & CCB_URGENT) != 0)
1622         {
1623                 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1624         }
1625         else
1626         {
1627                 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
1628         }
1629
1630         slp->sl_nio ++;
1631
1632         if (slp->sl_Tnexus == NULL)
1633                 scsi_low_start(slp);
1634         return 0;
1635 }
1636
1637 static int
1638 scsi_low_message_enqueue(struct scsi_low_softc *slp, struct targ_info *ti,
1639                          struct lun_info *li, u_int flags)
1640 {
1641         struct slccb *cb;
1642         u_int tmsgflags;
1643
1644         tmsgflags = ti->ti_setup_msg;
1645         ti->ti_setup_msg = 0;
1646
1647         flags |= CCB_NORETRY;
1648         if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
1649                 return ENOMEM;
1650
1651         cb->osdep = NULL;
1652         cb->bp = NULL;
1653         scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
1654         return 0;
1655 }
1656
1657 /**************************************************************
1658  * Generic Start & Done
1659  **************************************************************/
1660 #define SLSC_MODE_SENSE_SHORT   0x1a
1661 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0}; 
1662 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0, 
1663                               sizeof(struct scsi_low_mode_sense_data), 0}; 
1664 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0, 
1665                               sizeof(struct scsi_low_inq_data), 0}; 
1666 static u_int8_t unit_ready_cmd[6];
1667 static int scsi_low_setup_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1668 static int scsi_low_sense_abort_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
1669 static int scsi_low_resume (struct scsi_low_softc *);
1670
1671 static void
1672 scsi_low_unit_ready_cmd(struct slccb *cb)
1673 {
1674         cb->ccb_scp.scp_cmd = unit_ready_cmd;
1675         cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
1676         cb->ccb_scp.scp_datalen = 0;
1677         cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1678         cb->ccb_tcmax = 15;
1679 }
1680
1681 static int
1682 scsi_low_sense_abort_start(struct scsi_low_softc *slp, struct targ_info *ti,
1683                            struct lun_info *li, struct slccb *cb)
1684 {
1685         cb->ccb_scp.scp_cmdlen = 6;
1686         SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
1687         cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
1688         cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
1689         cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
1690         cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
1691         cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
1692         cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1693         cb->ccb_tcmax = 15;
1694         scsi_low_ccb_message_clear(cb);
1695         if ((cb->ccb_flags & CCB_CLEARQ) != 0)
1696         {
1697                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
1698         }
1699         else
1700         {
1701                 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
1702 #ifdef  SCSI_LOW_NEGOTIATE_BEFORE_SENSE
1703                 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
1704 #endif  /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
1705         }
1706
1707         return SCSI_LOW_START_NO_QTAG;
1708 }
1709
1710 static int
1711 scsi_low_setup_start(struct scsi_low_softc *slp, struct targ_info *ti,
1712                      struct lun_info *li, struct slccb *cb)
1713 {
1714         switch(li->li_state)
1715         {
1716         case SCSI_LOW_LUN_SLEEP:
1717                 scsi_low_unit_ready_cmd(cb);
1718                 break;
1719
1720         case SCSI_LOW_LUN_START:
1721                 cb->ccb_scp.scp_cmd = ss_cmd;
1722                 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
1723                 cb->ccb_scp.scp_datalen = 0;
1724                 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1725                 cb->ccb_tcmax = 30;
1726                 break;
1727
1728         case SCSI_LOW_LUN_INQ:
1729                 cb->ccb_scp.scp_cmd = inq_cmd;
1730                 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
1731                 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
1732                 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
1733                 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1734                 cb->ccb_tcmax = 15;
1735                 break;
1736
1737         case SCSI_LOW_LUN_MODEQ:
1738                 cb->ccb_scp.scp_cmd = sms_cmd;
1739                 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
1740                 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
1741                 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
1742                 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1743                 cb->ccb_tcmax = 15;
1744                 return SCSI_LOW_START_QTAG;
1745
1746         default:
1747                 panic("%s: no setup phase", slp->sl_xname);
1748         }
1749
1750         return SCSI_LOW_START_NO_QTAG;
1751 }
1752
1753 static int
1754 scsi_low_resume(struct scsi_low_softc *slp)
1755 {
1756         if (slp->sl_flags & HW_RESUME)
1757                 return EJUSTRETURN;
1758         slp->sl_flags &= ~HW_POWDOWN;
1759         if (slp->sl_funcs->scsi_low_power != NULL)
1760         {
1761                 slp->sl_flags |= HW_RESUME;
1762                 slp->sl_rstep = 0;
1763                 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1764                 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1765                                         (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
1766                                          SCSI_LOW_TIMEOUT_START);
1767                 return EJUSTRETURN;
1768         }
1769         return 0;
1770 }
1771
1772 static void
1773 scsi_low_start(struct scsi_low_softc *slp)
1774 {
1775         struct targ_info *ti;
1776         struct lun_info *li;
1777         struct slccb *cb;
1778         int rv;
1779
1780         /* check hardware exists or under initializations ? */
1781         if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
1782                 return;
1783
1784         /* check hardware power up ? */
1785         if ((slp->sl_flags & HW_POWERCTRL) != 0)
1786         {
1787                 slp->sl_active ++;
1788                 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
1789                 {
1790                         if (scsi_low_resume(slp) == EJUSTRETURN)
1791                                 return;
1792                 }
1793         }
1794
1795         /* setup nexus */
1796 #ifdef  SCSI_LOW_DIAGNOSTIC
1797         if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
1798         {
1799                 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
1800                 panic("%s: inconsistent", slp->sl_xname);
1801         }
1802 #endif  /* SCSI_LOW_DIAGNOSTIC */
1803
1804         for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
1805              cb = TAILQ_NEXT(cb, ccb_chain))
1806         {
1807                 li = cb->li;
1808
1809                 if (li->li_disc == 0)
1810                 {
1811                         goto scsi_low_cmd_start;
1812                 }
1813                 else if (li->li_nqio > 0)
1814                 {
1815                         if (li->li_nqio < li->li_maxnqio ||
1816                             (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1817                                 goto scsi_low_cmd_start;
1818                 }
1819         }
1820         return;
1821
1822 scsi_low_cmd_start:
1823         cb->ccb_flags &= ~CCB_STARTQ;
1824         TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
1825         ti = cb->ti;
1826
1827         /* clear all error flag bits (for restart) */
1828         cb->ccb_error = 0;
1829         cb->ccb_datalen = -1;
1830         cb->ccb_scp.scp_status = ST_UNKNOWN;
1831
1832         /* setup nexus pointer */
1833         slp->sl_Qnexus = cb;
1834         slp->sl_Lnexus = li;
1835         slp->sl_Tnexus = ti;
1836
1837         /* initialize msgsys */
1838         scsi_low_init_msgsys(slp, ti);
1839
1840         /* exec cmd */
1841         if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
1842         {
1843                 /* CA state or forced abort */
1844                 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
1845         }
1846         else if (li->li_state >= SCSI_LOW_LUN_OK)
1847         {
1848                 cb->ccb_flags &= ~CCB_INTERNAL;
1849                 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
1850                 if (cb->ccb_msgoutflag != 0)
1851                 {
1852                         scsi_low_ccb_message_exec(slp, cb);
1853                 }
1854         }
1855         else
1856         {
1857                 cb->ccb_flags |= CCB_INTERNAL;
1858                 rv = scsi_low_setup_start(slp, ti, li, cb);
1859         }
1860
1861         /* allocate qtag */
1862 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
1863
1864         if (rv == SCSI_LOW_START_QTAG &&
1865             (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
1866             li->li_maxnqio > 0)
1867         {
1868                 u_int qmsg;
1869
1870                 scsi_low_activate_qtag(cb);
1871                 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1872                      SCSI_LOW_CMD_ORDERED_QTAG) != 0)
1873                         qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
1874                 else if ((cb->ccb_flags & CCB_URGENT) != 0)
1875                         qmsg = SCSI_LOW_MSG_HEAD_QTAG;
1876                 else
1877                         qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
1878                 scsi_low_assert_msg(slp, ti, qmsg, 0);
1879         }
1880
1881         /* timeout */
1882         if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
1883                 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
1884         cb->ccb_tc = cb->ccb_tcmax;
1885
1886         /* setup saved scsi data pointer */
1887         cb->ccb_sscp = cb->ccb_scp;
1888
1889         /* setup current scsi pointer */ 
1890         slp->sl_scp = cb->ccb_sscp;
1891         slp->sl_error = cb->ccb_error;
1892
1893         /* assert always an identify msg */
1894         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
1895
1896         /* debug section */
1897 #ifdef  SCSI_LOW_DIAGNOSTIC
1898         scsi_low_msg_log_init(&ti->ti_log_msgin);
1899         scsi_low_msg_log_init(&ti->ti_log_msgout);
1900 #endif  /* SCSI_LOW_DIAGNOSTIC */
1901
1902         /* selection start */
1903         slp->sl_selid = cb;
1904         rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
1905         if (rv == SCSI_LOW_START_OK)
1906         {
1907 #ifdef  SCSI_LOW_STATICS
1908                 scsi_low_statics.nexus_win ++;
1909 #endif  /* SCSI_LOW_STATICS */
1910                 return;
1911         }
1912
1913         scsi_low_arbit_fail(slp, cb);
1914 #ifdef  SCSI_LOW_STATICS
1915         scsi_low_statics.nexus_fail ++;
1916 #endif  /* SCSI_LOW_STATICS */
1917 }
1918
1919 void
1920 scsi_low_arbit_fail(struct scsi_low_softc *slp, struct slccb *cb)
1921 {
1922         struct targ_info *ti = cb->ti;
1923
1924         scsi_low_deactivate_qtag(cb);
1925         scsi_low_ccb_message_retry(cb);
1926         cb->ccb_flags |= CCB_STARTQ;
1927         TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
1928
1929         scsi_low_bus_release(slp, ti);
1930
1931         cb->ccb_selrcnt ++;
1932         if (slp->sl_disc == 0)
1933         {
1934 #ifdef  SCSI_LOW_DIAGNOSTIC
1935                 printf("%s: try selection again\n", slp->sl_xname);
1936 #endif  /* SCSI_LOW_DIAGNOSTIC */
1937                 slp->sl_retry_sel = 1;
1938         }
1939 }
1940
1941 static void
1942 scsi_low_bus_release(struct scsi_low_softc *slp, struct targ_info *ti)
1943 {
1944         if (ti->ti_disc > 0)
1945         {
1946                 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
1947         }
1948         else
1949         {
1950                 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
1951         }
1952
1953         /* clear all nexus pointer */
1954         slp->sl_Qnexus = NULL;
1955         slp->sl_Lnexus = NULL;
1956         slp->sl_Tnexus = NULL;
1957
1958         /* clear selection assert */
1959         slp->sl_selid = NULL;
1960
1961         /* clear nexus data */
1962         slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
1963
1964         /* clear phase change counter */
1965         slp->sl_ph_count = 0;
1966 }
1967
1968 static int
1969 scsi_low_setup_done(struct scsi_low_softc *slp, struct slccb *cb)
1970 {
1971         struct targ_info *ti;
1972         struct lun_info *li;
1973
1974         ti = cb->ti;
1975         li = cb->li;
1976
1977         if (cb->ccb_rcnt >= slp->sl_max_retry)
1978         {
1979                 cb->ccb_error |= ABORTIO;
1980                 return SCSI_LOW_DONE_COMPLETE;
1981         }
1982
1983         /* XXX: special huck for selection timeout */
1984         if (li->li_state == SCSI_LOW_LUN_SLEEP &&
1985             (cb->ccb_error & SELTIMEOUTIO) != 0)
1986         {
1987                 cb->ccb_error |= ABORTIO;
1988                 return SCSI_LOW_DONE_COMPLETE;
1989         }
1990
1991         switch(li->li_state)
1992         {
1993         case SCSI_LOW_LUN_INQ:
1994                 if (cb->ccb_error != 0)
1995                 {
1996                         li->li_diskflags &= 
1997                                 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
1998                         if (li->li_lun > 0)
1999                                 goto resume;
2000                         ti->ti_diskflags &=
2001                                 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2002                 }
2003                 else if ((li->li_inq.sd_version & 7) >= 2 ||
2004                          (li->li_inq.sd_len >= 4))
2005                 {
2006                         if ((li->li_inq.sd_support & 0x2) == 0)
2007                                 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2008                         if ((li->li_inq.sd_support & 0x8) == 0)
2009                                 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2010                         if (li->li_lun > 0)
2011                                 goto resume;
2012                         if ((li->li_inq.sd_support & 0x10) == 0)
2013                                 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2014                         if ((li->li_inq.sd_support & 0x20) == 0)
2015                                 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2016                         if ((li->li_inq.sd_support & 0x40) == 0)
2017                                 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2018                 }
2019                 else
2020                 {
2021                         li->li_diskflags &= 
2022                                 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2023                         if (li->li_lun > 0)
2024                                 goto resume;
2025                         ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2026                 }
2027                 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2028 resume:
2029                 scsi_low_calcf_target(ti);
2030                 scsi_low_calcf_lun(li);
2031                 break;
2032
2033         case SCSI_LOW_LUN_MODEQ:
2034                 if (cb->ccb_error != 0)
2035                 {
2036                         if (cb->ccb_error & SENSEIO)
2037                         {
2038 #ifdef  SCSI_LOW_DEBUG
2039                                 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2040                                 {
2041                                         printf("SENSE: [%x][%x][%x][%x][%x]\n",
2042                                         (u_int) cb->ccb_sense.error_code,
2043                                         (u_int) cb->ccb_sense.segment,
2044                                         (u_int) cb->ccb_sense.flags,
2045                                         (u_int) cb->ccb_sense.add_sense_code,
2046                                         (u_int) cb->ccb_sense.add_sense_code_qual);
2047                                 }
2048 #endif  /* SCSI_LOW_DEBUG */
2049                         }
2050                         else
2051                         {
2052                                 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2053                         }
2054                 }
2055                 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2056                 {       
2057                         if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2058                                 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2059                         else
2060                                 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2061                         if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2062                                 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2063                 }
2064                 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2065                 scsi_low_calcf_lun(li);
2066                 break;
2067
2068         default:
2069                 break;
2070         }
2071
2072         li->li_state ++;
2073         if (li->li_state == SCSI_LOW_LUN_OK)
2074         {
2075                 scsi_low_calcf_target(ti);
2076                 scsi_low_calcf_lun(li);
2077                 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2078                     (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2079                 {
2080                         scsi_low_calcf_show(li);
2081                 }       
2082         }
2083
2084         cb->ccb_rcnt --;
2085         return SCSI_LOW_DONE_RETRY;
2086 }
2087
2088 static int
2089 scsi_low_done(struct scsi_low_softc *slp, struct slccb *cb)
2090 {
2091         int rv;
2092
2093         if (cb->ccb_error == 0)
2094         {
2095                 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2096                 {
2097 #ifdef  SCSI_LOW_QCLEAR_AFTER_CA
2098                         /* XXX:
2099                          * SCSI-2 draft suggests 
2100                          * page 0x0a QErr bit determins if
2101                          * the target aborts or continues
2102                          * the queueing io's after CA state resolved.
2103                          * However many targets seem not to support
2104                          * the page 0x0a. Thus we should manually clear the
2105                          * queuing io's after CA state.
2106                          */
2107                         if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2108                         {
2109                                 cb->ccb_rcnt --;
2110                                 cb->ccb_flags |= CCB_CLEARQ;
2111                                 goto retry;
2112                         }
2113 #endif  /* SCSI_LOW_QCLEAR_AFTER_CA */
2114
2115                         if ((cb->ccb_flags & CCB_SENSE) != 0)
2116                                 cb->ccb_error |= (SENSEIO | ABORTIO);
2117                         cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2118                 }
2119                 else switch (cb->ccb_sscp.scp_status)
2120                 {
2121                 case ST_GOOD:
2122                 case ST_MET:
2123                 case ST_INTERGOOD:
2124                 case ST_INTERMET:
2125                         if (cb->ccb_datalen == 0 ||
2126                             cb->ccb_scp.scp_datalen == 0)
2127                                 break;
2128
2129                         if (cb->ccb_scp.scp_cmdlen > 0 &&
2130                             (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2131                              SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2132                                 break;
2133
2134                         cb->ccb_error |= PDMAERR;
2135                         break;
2136
2137                 case ST_BUSY:
2138                 case ST_QUEFULL:
2139                         cb->ccb_error |= (BUSYERR | STATERR);
2140                         break;
2141
2142                 case ST_CONFLICT:
2143                         cb->ccb_error |= (STATERR | ABORTIO);
2144                         break;
2145
2146                 case ST_CHKCOND:
2147                 case ST_CMDTERM:
2148                         if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2149                         {
2150                                 cb->ccb_rcnt --;
2151                                 cb->ccb_flags |= CCB_SENSE;
2152                                 goto retry;
2153                         }
2154                         cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2155                         break;
2156
2157                 case ST_UNKNOWN:
2158                 default:
2159                         cb->ccb_error |= FATALIO;
2160                         break;
2161                 }
2162         }
2163         else
2164         {
2165                 if (cb->ccb_flags & CCB_SENSE)
2166                 {
2167                         cb->ccb_error |= (SENSEERR | ABORTIO);
2168                 }
2169                 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2170         }
2171
2172         /* internal ccb */
2173         if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2174         {
2175                 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2176                         goto retry;
2177         }
2178
2179         /* check a ccb msgout flag */
2180         if (cb->ccb_omsgoutflag != 0)
2181         {
2182 #define SCSI_LOW_MSG_ABORT_OK   (SCSI_LOW_MSG_ABORT | \
2183                                  SCSI_LOW_MSG_ABORT_QTAG | \
2184                                  SCSI_LOW_MSG_CLEAR_QTAG | \
2185                                  SCSI_LOW_MSG_TERMIO)
2186
2187                 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2188                 {
2189                         cb->ccb_error |= ABORTIO;
2190                 }
2191         }
2192
2193         /* call OS depend done */
2194         if (cb->osdep != NULL)
2195         {
2196                 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2197                 if (rv == EJUSTRETURN)
2198                         goto retry;
2199         }
2200         else if (cb->ccb_error != 0)
2201         {
2202                 if (cb->ccb_rcnt >= slp->sl_max_retry)
2203                         cb->ccb_error |= ABORTIO;
2204
2205                 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2206                     (cb->ccb_error & ABORTIO) == 0)
2207                         goto retry;
2208         }
2209
2210         /* free our target */
2211 #ifdef  SCSI_LOW_DEBUG
2212         if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2213         {
2214                 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2215                 scsi_low_print(slp, NULL);
2216         }
2217 #endif  /* SCSI_LOW_DEBUG */
2218
2219         scsi_low_deactivate_qtag(cb);
2220         scsi_low_dealloc_qtag(cb);
2221         scsi_low_free_ccb(cb);
2222         slp->sl_nio --;
2223         return SCSI_LOW_DONE_COMPLETE;
2224
2225 retry:
2226 #ifdef  SCSI_LOW_DEBUG
2227         if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2228         {
2229                 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2230                 scsi_low_print(slp, NULL);
2231         }
2232 #endif  /* SCSI_LOW_DEBUG */
2233                 
2234         cb->ccb_rcnt ++;
2235         scsi_low_deactivate_qtag(cb);
2236         scsi_low_ccb_message_retry(cb);
2237         return SCSI_LOW_DONE_RETRY;
2238 }
2239
2240 /**************************************************************
2241  * Reset
2242  **************************************************************/
2243 static void
2244 scsi_low_reset_nexus_target(struct scsi_low_softc *slp, struct targ_info *ti,
2245                             int fdone)
2246 {
2247         struct lun_info *li;
2248
2249         for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2250              li = LIST_NEXT(li, lun_chain))
2251         {
2252                 scsi_low_reset_nexus_lun(slp, li, fdone);
2253                 li->li_state = SCSI_LOW_LUN_SLEEP;
2254                 li->li_maxnqio = 0;
2255         }
2256
2257         ti->ti_disc = 0;
2258         ti->ti_setup_msg = 0;
2259         ti->ti_setup_msg_done = 0;
2260
2261         ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2262         ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2263
2264         ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2265         ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2266
2267         if (slp->sl_funcs->scsi_low_targ_init != NULL)
2268         {
2269                 ((*slp->sl_funcs->scsi_low_targ_init)
2270                         (slp, ti, SCSI_LOW_INFO_REVOKE));
2271         }
2272         scsi_low_calcf_target(ti);
2273
2274         for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2275              li = LIST_NEXT(li, lun_chain))
2276         {
2277                 li->li_flags = 0;
2278
2279                 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2280                 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2281
2282                 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2283                 {
2284                         ((*slp->sl_funcs->scsi_low_lun_init)
2285                                 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2286                 }
2287                 scsi_low_calcf_lun(li);
2288         }
2289 }
2290
2291 static void
2292 scsi_low_reset_nexus(struct scsi_low_softc *slp, int fdone)
2293 {
2294         struct targ_info *ti;
2295         struct slccb *cb, *topcb;
2296
2297         if ((cb = slp->sl_Qnexus) != NULL)
2298         {
2299                 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2300         }
2301         else
2302         {
2303                 topcb = NULL;
2304         }
2305
2306         for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2307              ti = TAILQ_NEXT(ti, ti_chain))
2308         {
2309                 scsi_low_reset_nexus_target(slp, ti, fdone);
2310                 scsi_low_bus_release(slp, ti);
2311                 scsi_low_init_msgsys(slp, ti);
2312         }
2313
2314         if (topcb != NULL)
2315         {
2316                 topcb->ccb_flags |= CCB_STARTQ;
2317                 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2318         }
2319
2320         slp->sl_disc = 0;
2321         slp->sl_retry_sel = 0;
2322         slp->sl_flags &= ~HW_PDMASTART;
2323 }
2324
2325 /* misc */
2326 static int tw_pos;
2327 static char tw_chars[] = "|/-\\";
2328 #define TWIDDLEWAIT             10000
2329
2330 static void
2331 scsi_low_twiddle_wait(void)
2332 {
2333         cnputc('\b');
2334         cnputc(tw_chars[tw_pos++]);
2335         tw_pos %= (sizeof(tw_chars) - 1);
2336         SCSI_LOW_DELAY(TWIDDLEWAIT);
2337 }
2338
2339 void
2340 scsi_low_bus_reset(struct scsi_low_softc *slp)
2341 {
2342         int i;
2343
2344         (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2345
2346         printf("%s: try to reset scsi bus  ", slp->sl_xname);
2347         for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2348                 scsi_low_twiddle_wait();
2349         cnputc('\b');
2350         printf("\n");
2351 }
2352
2353 int
2354 scsi_low_restart(struct scsi_low_softc *slp, int flags, u_char *s)
2355 {
2356         int error;
2357
2358         if (s != NULL)
2359                 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
2360
2361         if ((error = scsi_low_init(slp, flags)) != 0)
2362                 return error;
2363
2364         scsi_low_start(slp);
2365         return 0;
2366 }
2367
2368 /**************************************************************
2369  * disconnect and reselect
2370  **************************************************************/
2371 #define MSGCMD_LUN(msg) (msg & 0x07)
2372
2373 static struct slccb *
2374 scsi_low_establish_ccb(struct targ_info *ti, struct lun_info *li, scsi_low_tag_t tag)
2375 {
2376         struct scsi_low_softc *slp = ti->ti_sc;
2377         struct slccb *cb;
2378
2379         if (li == NULL)
2380                 return NULL;
2381
2382         cb = TAILQ_FIRST(&li->li_discq);
2383         for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
2384                 if (cb->ccb_tag == tag)
2385                         goto found;
2386         return cb;
2387
2388         /* 
2389          * establish our ccb nexus
2390          */
2391 found:
2392 #ifdef  SCSI_LOW_DEBUG
2393         if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
2394         {
2395                 printf("%s: nexus(0x%lx) abort check start\n",
2396                         slp->sl_xname, (u_long) cb);
2397                 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
2398                 scsi_low_revoke_ccb(slp, cb, 1);
2399                 return NULL;
2400         }
2401
2402         if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
2403         {
2404                 if (cb->ccb_omsgoutflag == 0)
2405                         scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
2406         }
2407 #endif  /* SCSI_LOW_DEBUG */
2408
2409         TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
2410         cb->ccb_flags &= ~CCB_DISCQ;
2411         slp->sl_Qnexus = cb;
2412
2413         slp->sl_scp = cb->ccb_sscp;
2414         slp->sl_error |= cb->ccb_error;
2415
2416         slp->sl_disc --;
2417         ti->ti_disc --;
2418         li->li_disc --;
2419
2420         /* inform "ccb nexus established" to the host driver */
2421         (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2422
2423         /* check msg */
2424         if (cb->ccb_msgoutflag != 0)
2425         {
2426                 scsi_low_ccb_message_exec(slp, cb);
2427         }
2428
2429         return cb;
2430 }
2431
2432 struct targ_info *
2433 scsi_low_reselected(struct scsi_low_softc *slp, u_int targ)
2434 {
2435         struct targ_info *ti;
2436         struct slccb *cb;
2437         u_char *s;
2438
2439         /* 
2440          * Check select vs reselected collision.
2441          */
2442
2443         if ((cb = slp->sl_selid) != NULL)
2444         {
2445                 scsi_low_arbit_fail(slp, cb);
2446 #ifdef  SCSI_LOW_STATICS
2447                 scsi_low_statics.nexus_conflict ++;
2448 #endif  /* SCSI_LOW_STATICS */
2449         }
2450
2451         /* 
2452          * Check if no current active nexus.
2453          */
2454         if (slp->sl_Tnexus != NULL)
2455         {
2456                 s = "host busy";
2457                 goto world_restart;
2458         }
2459
2460         /* 
2461          * Check a valid target id asserted ?
2462          */
2463         if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
2464         {
2465                 s = "scsi id illegal";
2466                 goto world_restart;
2467         }
2468
2469         /* 
2470          * Check the target scsi status.
2471          */
2472         ti = slp->sl_ti[targ];
2473         if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
2474         {
2475                 s = "phase mismatch";
2476                 goto world_restart;
2477         }
2478
2479         /* 
2480          * Setup init msgsys
2481          */
2482         slp->sl_error = 0;
2483         scsi_low_init_msgsys(slp, ti);
2484
2485         /* 
2486          * Establish our target nexus
2487          */
2488         SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
2489         slp->sl_Tnexus = ti;
2490 #ifdef  SCSI_LOW_STATICS
2491         scsi_low_statics.nexus_reselected ++;
2492 #endif  /* SCSI_LOW_STATICS */
2493         return ti;
2494
2495 world_restart:
2496         printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
2497         scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, 
2498                          "reselect: scsi world confused");
2499         return NULL;
2500 }
2501
2502 /**************************************************************
2503  * cmd out pointer setup
2504  **************************************************************/
2505 int
2506 scsi_low_cmd(struct scsi_low_softc *slp, struct targ_info *ti)
2507 {
2508         struct slccb *cb = slp->sl_Qnexus;
2509         
2510         slp->sl_ph_count ++;
2511         if (cb == NULL)
2512         {
2513                 /*
2514                  * no ccb, abort!
2515                  */
2516                 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
2517                 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2518                 slp->sl_scp.scp_datalen = 0;
2519                 slp->sl_scp.scp_direction = SCSI_LOW_READ;
2520                 slp->sl_error |= FATALIO;
2521                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2522                 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
2523                 return EINVAL;
2524         }
2525         else 
2526         {
2527 #ifdef  SCSI_LOW_DEBUG
2528                 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
2529                 {
2530                         scsi_low_test_cmdlnk(slp, cb);
2531                 }
2532 #endif  /* SCSI_LOW_DEBUG */
2533         }
2534         return 0;
2535 }
2536
2537 /**************************************************************
2538  * data out pointer setup
2539  **************************************************************/
2540 int
2541 scsi_low_data(struct scsi_low_softc *slp, struct targ_info *ti,
2542               struct buf **bp, int direction)
2543 {
2544         struct slccb *cb = slp->sl_Qnexus;
2545
2546         if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
2547         {
2548                 *bp = cb->bp;
2549                 return 0;
2550         }
2551
2552         slp->sl_error |= (FATALIO | PDMAERR);
2553         slp->sl_scp.scp_datalen = 0;
2554         slp->sl_scp.scp_direction = direction;
2555         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2556         if (ti->ti_ophase != ti->ti_phase)
2557         {
2558                 char *s;
2559
2560                 if (cb == NULL)
2561                         s = "DATA PHASE: ccb nexus not found";
2562                 else
2563                         s = "DATA PHASE: xfer direction mismatch";
2564                 SCSI_LOW_INFO(slp, ti, s);
2565         }
2566
2567         *bp = NULL;
2568         return EINVAL;
2569 }
2570
2571 /**************************************************************
2572  * MSG_SYS 
2573  **************************************************************/
2574 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
2575 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
2576 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
2577 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
2578 #define MSGIN_DATA_LAST 0x30
2579
2580 static int scsi_low_errfunc_synch (struct scsi_low_softc *, u_int);
2581 static int scsi_low_errfunc_wide (struct scsi_low_softc *, u_int);
2582 static int scsi_low_errfunc_identify (struct scsi_low_softc *, u_int);
2583 static int scsi_low_errfunc_qtag (struct scsi_low_softc *, u_int);
2584
2585 static int scsi_low_msgfunc_synch (struct scsi_low_softc *);
2586 static int scsi_low_msgfunc_wide (struct scsi_low_softc *);
2587 static int scsi_low_msgfunc_identify (struct scsi_low_softc *);
2588 static int scsi_low_msgfunc_abort (struct scsi_low_softc *);
2589 static int scsi_low_msgfunc_qabort (struct scsi_low_softc *);
2590 static int scsi_low_msgfunc_qtag (struct scsi_low_softc *);
2591 static int scsi_low_msgfunc_reset (struct scsi_low_softc *);
2592
2593 struct scsi_low_msgout_data {
2594         u_int   md_flags;
2595         u_int8_t md_msg;
2596         int (*md_msgfunc) (struct scsi_low_softc *);
2597         int (*md_errfunc) (struct scsi_low_softc *, u_int);
2598 #define MSG_RELEASE_ATN 0x0001
2599         u_int md_condition;
2600 };
2601
2602 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
2603 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
2604 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
2605 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
2606 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
2607 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
2608 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2609 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
2610 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG,  MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2611 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2612 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG,  MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
2613 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL,  MSG_RELEASE_ATN},
2614 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
2615 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
2616 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
2617 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
2618 /* 15 */{SCSI_LOW_MSG_ALL, 0},
2619 };
2620
2621 static int scsi_low_msginfunc_ext (struct scsi_low_softc *);
2622 static int scsi_low_synch (struct scsi_low_softc *);
2623 static int scsi_low_wide (struct scsi_low_softc *);
2624 static int scsi_low_msginfunc_msg_reject (struct scsi_low_softc *);
2625 static int scsi_low_msginfunc_rejop (struct scsi_low_softc *);
2626 static int scsi_low_msginfunc_rp (struct scsi_low_softc *);
2627 static int scsi_low_msginfunc_sdp (struct scsi_low_softc *);
2628 static int scsi_low_msginfunc_disc (struct scsi_low_softc *);
2629 static int scsi_low_msginfunc_cc (struct scsi_low_softc *);
2630 static int scsi_low_msginfunc_lcc (struct scsi_low_softc *);
2631 static int scsi_low_msginfunc_parity (struct scsi_low_softc *);
2632 static int scsi_low_msginfunc_noop (struct scsi_low_softc *);
2633 static int scsi_low_msginfunc_simple_qtag (struct scsi_low_softc *);
2634 static int scsi_low_msginfunc_i_wide_residue (struct scsi_low_softc *);
2635
2636 struct scsi_low_msgin_data {
2637         u_int md_len;
2638         int (*md_msgfunc) (struct scsi_low_softc *);
2639 };
2640
2641 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
2642 /* 0 */ {1,     scsi_low_msginfunc_cc},
2643 /* 1 */ {2,     scsi_low_msginfunc_ext},
2644 /* 2 */ {1,     scsi_low_msginfunc_sdp},
2645 /* 3 */ {1,     scsi_low_msginfunc_rp},
2646 /* 4 */ {1,     scsi_low_msginfunc_disc},
2647 /* 5 */ {1,     scsi_low_msginfunc_rejop},
2648 /* 6 */ {1,     scsi_low_msginfunc_rejop},
2649 /* 7 */ {1,     scsi_low_msginfunc_msg_reject},
2650 /* 8 */ {1,     scsi_low_msginfunc_noop},
2651 /* 9 */ {1,     scsi_low_msginfunc_parity},
2652 /* a */ {1,     scsi_low_msginfunc_lcc},
2653 /* b */ {1,     scsi_low_msginfunc_lcc},
2654 /* c */ {1,     scsi_low_msginfunc_rejop},
2655 /* d */ {2,     scsi_low_msginfunc_rejop},
2656 /* e */ {1,     scsi_low_msginfunc_rejop},
2657 /* f */ {1,     scsi_low_msginfunc_rejop},
2658 /* 0x10 */ {1,  scsi_low_msginfunc_rejop},
2659 /* 0x11 */ {1,  scsi_low_msginfunc_rejop},
2660 /* 0x12 */ {1,  scsi_low_msginfunc_rejop},
2661 /* 0x13 */ {1,  scsi_low_msginfunc_rejop},
2662 /* 0x14 */ {1,  scsi_low_msginfunc_rejop},
2663 /* 0x15 */ {1,  scsi_low_msginfunc_rejop},
2664 /* 0x16 */ {1,  scsi_low_msginfunc_rejop},
2665 /* 0x17 */ {1,  scsi_low_msginfunc_rejop},
2666 /* 0x18 */ {1,  scsi_low_msginfunc_rejop},
2667 /* 0x19 */ {1,  scsi_low_msginfunc_rejop},
2668 /* 0x1a */ {1,  scsi_low_msginfunc_rejop},
2669 /* 0x1b */ {1,  scsi_low_msginfunc_rejop},
2670 /* 0x1c */ {1,  scsi_low_msginfunc_rejop},
2671 /* 0x1d */ {1,  scsi_low_msginfunc_rejop},
2672 /* 0x1e */ {1,  scsi_low_msginfunc_rejop},
2673 /* 0x1f */ {1,  scsi_low_msginfunc_rejop},
2674 /* 0x20 */ {2,  scsi_low_msginfunc_simple_qtag},
2675 /* 0x21 */ {2,  scsi_low_msginfunc_rejop},
2676 /* 0x22 */ {2,  scsi_low_msginfunc_rejop},
2677 /* 0x23 */ {2,  scsi_low_msginfunc_i_wide_residue},
2678 /* 0x24 */ {2,  scsi_low_msginfunc_rejop},
2679 /* 0x25 */ {2,  scsi_low_msginfunc_rejop},
2680 /* 0x26 */ {2,  scsi_low_msginfunc_rejop},
2681 /* 0x27 */ {2,  scsi_low_msginfunc_rejop},
2682 /* 0x28 */ {2,  scsi_low_msginfunc_rejop},
2683 /* 0x29 */ {2,  scsi_low_msginfunc_rejop},
2684 /* 0x2a */ {2,  scsi_low_msginfunc_rejop},
2685 /* 0x2b */ {2,  scsi_low_msginfunc_rejop},
2686 /* 0x2c */ {2,  scsi_low_msginfunc_rejop},
2687 /* 0x2d */ {2,  scsi_low_msginfunc_rejop},
2688 /* 0x2e */ {2,  scsi_low_msginfunc_rejop},
2689 /* 0x2f */ {2,  scsi_low_msginfunc_rejop},
2690 /* 0x30 */ {1,  scsi_low_msginfunc_rejop}       /* default rej op */
2691 };
2692
2693 /**************************************************************
2694  * msgout
2695  **************************************************************/
2696 static int
2697 scsi_low_msgfunc_synch(struct scsi_low_softc *slp)
2698 {
2699         struct targ_info *ti = slp->sl_Tnexus;
2700         int ptr = ti->ti_msgoutlen;
2701
2702         ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
2703         ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
2704         ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
2705         ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
2706         return MSG_EXTEND_SYNCHLEN + 2;
2707 }
2708
2709 static int
2710 scsi_low_msgfunc_wide(struct scsi_low_softc *slp)
2711 {
2712         struct targ_info *ti = slp->sl_Tnexus;
2713         int ptr = ti->ti_msgoutlen;
2714
2715         ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
2716         ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
2717         ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
2718         return MSG_EXTEND_WIDELEN + 2;
2719 }
2720
2721 static int
2722 scsi_low_msgfunc_identify(struct scsi_low_softc *slp)
2723 {
2724         struct targ_info *ti = slp->sl_Tnexus;
2725         struct lun_info *li = slp->sl_Lnexus;
2726         struct slccb *cb = slp->sl_Qnexus;
2727         int ptr = ti->ti_msgoutlen;
2728         u_int8_t msg;
2729
2730         msg = MSG_IDENTIFY;
2731         if (cb == NULL)
2732         {
2733                 slp->sl_error |= FATALIO;
2734                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2735                 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
2736         }
2737         else
2738         {
2739                 if (scsi_low_is_disconnect_ok(cb) != 0)
2740                         msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
2741                 else
2742                         msg |= li->li_lun;
2743
2744                 if (ti->ti_phase == PH_MSGOUT)
2745                 {
2746                         (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
2747                         if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2748                         {
2749                                 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2750                         }
2751                 }
2752         }
2753         ti->ti_msgoutstr[ptr + 0] = msg;
2754         return 1;
2755 }
2756
2757 static int
2758 scsi_low_msgfunc_abort(struct scsi_low_softc *slp)
2759 {
2760         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
2761         return 1;
2762 }
2763
2764 static int
2765 scsi_low_msgfunc_qabort(struct scsi_low_softc *slp)
2766 {
2767         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
2768         return 1;
2769 }
2770
2771 static int
2772 scsi_low_msgfunc_reset(struct scsi_low_softc *slp)
2773 {
2774         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
2775         return 1;
2776 }
2777
2778 static int
2779 scsi_low_msgfunc_qtag(struct scsi_low_softc *slp)
2780 {
2781         struct targ_info *ti = slp->sl_Tnexus;
2782         struct slccb *cb = slp->sl_Qnexus;
2783         int ptr = ti->ti_msgoutlen;
2784
2785         if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
2786         {
2787                 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
2788                 return 1;
2789         }
2790         else
2791         {
2792                 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
2793                 if (ti->ti_phase == PH_MSGOUT)
2794                 {
2795                         (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
2796                 }
2797         }
2798         return 2;
2799 }
2800
2801 /*
2802  * The following functions are called when targets give unexpected
2803  * responces in msgin (after msgout).
2804  */
2805 static int
2806 scsi_low_errfunc_identify(struct scsi_low_softc *slp, u_int msgflags)
2807 {
2808         if (slp->sl_Lnexus != NULL)
2809         {
2810                 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
2811                 scsi_low_calcf_lun(slp->sl_Lnexus);
2812         }
2813         return 0;
2814 }
2815
2816 static int
2817 scsi_low_errfunc_synch(struct scsi_low_softc *slp, u_int msgflags)
2818 {
2819         struct targ_info *ti = slp->sl_Tnexus;
2820
2821         MSGIN_PERIOD(ti) = 0;
2822         MSGIN_OFFSET(ti) = 0;
2823         scsi_low_synch(slp);
2824         return 0;
2825 }
2826
2827 static int
2828 scsi_low_errfunc_wide(struct scsi_low_softc *slp, u_int msgflags)
2829 {
2830         struct targ_info *ti = slp->sl_Tnexus;
2831
2832         MSGIN_WIDTHP(ti) = 0;
2833         scsi_low_wide(slp);
2834         return 0;
2835 }
2836
2837 static int
2838 scsi_low_errfunc_qtag(struct scsi_low_softc *slp, u_int msgflags)
2839 {
2840         if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
2841         {
2842                 if (slp->sl_Qnexus != NULL)
2843                 {
2844                         scsi_low_deactivate_qtag(slp->sl_Qnexus);
2845                 }
2846                 if (slp->sl_Lnexus != NULL)
2847                 {
2848                         slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
2849                         scsi_low_calcf_lun(slp->sl_Lnexus);
2850                 }
2851                 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
2852         }
2853         return 0;
2854 }
2855
2856
2857 int
2858 scsi_low_msgout(struct scsi_low_softc *slp, struct targ_info *ti, u_int fl)
2859 {
2860         struct scsi_low_msgout_data *mdp;
2861         int len = 0;
2862
2863 #ifdef  SCSI_LOW_DIAGNOSTIC
2864         if (ti != slp->sl_Tnexus)
2865         {
2866                 scsi_low_print(slp, NULL);
2867                 panic("scsi_low_msgout: Target nexus inconsistent");
2868         }
2869 #endif  /* SCSI_LOW_DIAGNOSTIC */
2870
2871         slp->sl_ph_count ++;
2872         if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
2873         {
2874                 printf("%s: too many phase changes\n", slp->sl_xname);
2875                 slp->sl_error |= FATALIO;
2876                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2877         }
2878                 
2879         /* STEP I.
2880          * Scsi phase changes.
2881          * Previously msgs asserted are accepted by our target or
2882          * processed by scsi_low_msgin.
2883          * Thus clear all saved informations.
2884          */
2885         if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
2886         {
2887                 ti->ti_omsgflags = 0;
2888                 ti->ti_emsgflags = 0;
2889         }
2890         else if (slp->sl_atten == 0)
2891         {
2892         /* STEP II.
2893          * We did not assert attention, however still our target required
2894          * msgs. Resend previous msgs. 
2895          */
2896                 ti->ti_msgflags |= ti->ti_omsgflags;
2897                 ti->ti_omsgflags = 0;
2898 #ifdef  SCSI_LOW_DIAGNOSTIC
2899                 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
2900 #endif  /* SCSI_LOW_DIAGNOSTIC */
2901         }
2902
2903         /* STEP III.
2904          * We have no msgs. send MSG_NOOP (OK?)
2905          */
2906         if (scsi_low_is_msgout_continue(ti, 0) == 0)
2907                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
2908
2909         /* STEP IV.
2910          * Process all msgs
2911          */
2912         ti->ti_msgoutlen = 0;
2913         slp->sl_clear_atten = 0;
2914         mdp = &scsi_low_msgout_data[0];
2915         for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
2916         {
2917                 if ((ti->ti_msgflags & mdp->md_flags) != 0)
2918                 {
2919                         ti->ti_omsgflags |= mdp->md_flags;
2920                         ti->ti_msgflags &= ~mdp->md_flags;
2921                         ti->ti_emsgflags = mdp->md_flags;
2922
2923                         ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
2924                         if (mdp->md_msgfunc != NULL)
2925                                 len = (*mdp->md_msgfunc) (slp);
2926                         else
2927                                 len = 1;
2928
2929 #ifdef  SCSI_LOW_DIAGNOSTIC
2930                         scsi_low_msg_log_write(&ti->ti_log_msgout,
2931                                &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
2932 #endif  /* SCSI_LOW_DIAGNOSTIC */
2933
2934                         ti->ti_msgoutlen += len;
2935                         if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
2936                         {
2937                                 slp->sl_clear_atten = 1;
2938                                 break;
2939                         }
2940
2941                         if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
2942                             ti->ti_msgflags == 0)
2943                                 break;
2944
2945                         if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
2946                                 break;
2947                 }
2948         }
2949
2950         if (scsi_low_is_msgout_continue(ti, 0) == 0)
2951                 slp->sl_clear_atten = 1;
2952
2953         return ti->ti_msgoutlen;
2954 }
2955
2956 /**************************************************************
2957  * msgin
2958  **************************************************************/
2959 static int
2960 scsi_low_msginfunc_noop(struct scsi_low_softc *slp)
2961 {
2962         return 0;
2963 }
2964
2965 static int
2966 scsi_low_msginfunc_rejop(struct scsi_low_softc *slp)
2967 {
2968         struct targ_info *ti = slp->sl_Tnexus;
2969         u_int8_t msg = ti->ti_msgin[0];
2970
2971         printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
2972         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
2973         return 0;
2974 }
2975
2976 static int
2977 scsi_low_msginfunc_cc(struct scsi_low_softc *slp)
2978 {
2979         struct lun_info *li;
2980
2981         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
2982
2983         /* validate status */
2984         if (slp->sl_Qnexus == NULL)
2985                 return ENOENT;
2986
2987         slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
2988         li = slp->sl_Lnexus;
2989         switch (slp->sl_scp.scp_status)
2990         {
2991         case ST_GOOD:
2992                 li->li_maxnqio = li->li_maxnexus;
2993                 break;
2994
2995         case ST_CHKCOND:
2996                 li->li_maxnqio = 0;
2997                 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
2998                         scsi_low_reset_nexus_lun(slp, li, 0);
2999                 break;
3000
3001         case ST_BUSY:
3002                 li->li_maxnqio = 0;
3003                 break;
3004
3005         case ST_QUEFULL:
3006                 if (li->li_maxnexus >= li->li_nqio)
3007                         li->li_maxnexus = li->li_nqio - 1;
3008                 li->li_maxnqio = li->li_maxnexus;
3009                 break;
3010
3011         case ST_INTERGOOD:
3012         case ST_INTERMET:
3013                 slp->sl_error |= MSGERR;
3014                 break;
3015
3016         default:
3017                 break;
3018         }
3019         return 0;
3020 }
3021
3022 static int
3023 scsi_low_msginfunc_lcc(struct scsi_low_softc *slp)
3024 {
3025         struct targ_info *ti;
3026         struct lun_info *li;
3027         struct slccb *ncb, *cb;
3028
3029         ti = slp->sl_Tnexus;
3030         li = slp->sl_Lnexus;
3031         if ((cb = slp->sl_Qnexus) == NULL)
3032                 goto bad;
3033                 
3034         cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3035         switch (slp->sl_scp.scp_status)
3036         {
3037         case ST_INTERGOOD:
3038         case ST_INTERMET:
3039                 li->li_maxnqio = li->li_maxnexus;
3040                 break;
3041
3042         default:
3043                 slp->sl_error |= MSGERR;
3044                 break;
3045         }
3046
3047         if ((li->li_flags & SCSI_LOW_LINK) == 0)
3048                 goto bad;
3049
3050         cb->ccb_error |= slp->sl_error;
3051         if (cb->ccb_error != 0)
3052                 goto bad;
3053
3054         for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3055              ncb = TAILQ_NEXT(ncb, ccb_chain))
3056         {
3057                 if (ncb->li == li)
3058                         goto cmd_link_start;
3059         }
3060
3061
3062 bad:
3063         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3064         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3065         return EIO;
3066
3067 cmd_link_start:
3068         ncb->ccb_flags &= ~CCB_STARTQ;
3069         TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3070
3071         scsi_low_dealloc_qtag(ncb);
3072         ncb->ccb_tag = cb->ccb_tag;
3073         ncb->ccb_otag = cb->ccb_otag;
3074         cb->ccb_tag = SCSI_LOW_UNKTAG;
3075         cb->ccb_otag = SCSI_LOW_UNKTAG;
3076         if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3077                 panic("%s: linked ccb retried", slp->sl_xname);
3078
3079         slp->sl_Qnexus = ncb;
3080         slp->sl_ph_count = 0;
3081
3082         ncb->ccb_error = 0;
3083         ncb->ccb_datalen = -1;
3084         ncb->ccb_scp.scp_status = ST_UNKNOWN;
3085         ncb->ccb_flags &= ~CCB_INTERNAL;
3086
3087         scsi_low_init_msgsys(slp, ti);
3088
3089         (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3090
3091         if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3092                 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3093         ncb->ccb_tc = ncb->ccb_tcmax;
3094
3095         /* setup saved scsi data pointer */
3096         ncb->ccb_sscp = ncb->ccb_scp;
3097         slp->sl_scp = ncb->ccb_sscp;
3098         slp->sl_error = ncb->ccb_error;
3099
3100 #ifdef  SCSI_LOW_DIAGNOSTIC
3101         scsi_low_msg_log_init(&ti->ti_log_msgin);
3102         scsi_low_msg_log_init(&ti->ti_log_msgout);
3103 #endif  /* SCSI_LOW_DIAGNOSTIC */
3104         return EJUSTRETURN;
3105 }
3106
3107 static int
3108 scsi_low_msginfunc_disc(struct scsi_low_softc *slp)
3109 {
3110         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3111         return 0;
3112 }
3113
3114 static int
3115 scsi_low_msginfunc_sdp(struct scsi_low_softc *slp)
3116 {
3117         struct slccb *cb = slp->sl_Qnexus;
3118
3119         if (cb != NULL)
3120         {
3121                 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3122                 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3123         }
3124         else
3125                 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3126         return 0;
3127 }
3128
3129 static int
3130 scsi_low_msginfunc_rp(struct scsi_low_softc *slp)
3131 {
3132         if (slp->sl_Qnexus != NULL)
3133                 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3134         else
3135                 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3136         return 0;
3137 }
3138
3139 static int
3140 scsi_low_synch(struct scsi_low_softc *slp)
3141 {
3142         struct targ_info *ti = slp->sl_Tnexus;
3143         u_int period = 0, offset = 0, speed;
3144         u_char *s;
3145         int error;
3146
3147         if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3148              MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3149              MSGIN_OFFSET(ti) == 0)
3150         {
3151                 if ((offset = MSGIN_OFFSET(ti)) != 0)
3152                         period = MSGIN_PERIOD(ti);
3153                 s = offset ? "synchronous" : "async";
3154         }
3155         else
3156         {
3157                 /* XXX:
3158                  * Target seems to be brain damaged.
3159                  * Force async transfer.
3160                  */
3161                 ti->ti_maxsynch.period = 0;
3162                 ti->ti_maxsynch.offset = 0;
3163                 printf("%s: target brain damaged. async transfer\n",
3164                         slp->sl_xname);
3165                 return EINVAL;
3166         }
3167
3168         ti->ti_maxsynch.period = period;
3169         ti->ti_maxsynch.offset = offset;
3170
3171         error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3172         if (error != 0)
3173         {
3174                 /* XXX:
3175                  * Current period and offset are not acceptable 
3176                  * for our adapter.
3177                  * The adapter changes max synch and max offset.
3178                  */
3179                 printf("%s: synch neg failed. retry synch msg neg ...\n",
3180                         slp->sl_xname);
3181                 return error;
3182         }
3183
3184         ti->ti_osynch = ti->ti_maxsynch;
3185         if (offset > 0)
3186         {
3187                 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3188         }
3189
3190         /* inform data */
3191         if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3192         {
3193 #ifdef  SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3194                 struct slccb *cb = slp->sl_Qnexus;
3195
3196                 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3197                         return 0;
3198 #endif  /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3199
3200                 printf("%s(%d:*): <%s> offset %d period %dns ",
3201                         slp->sl_xname, ti->ti_id, s, offset, period * 4);
3202
3203                 if (period != 0)
3204                 {
3205                         speed = 1000 * 10 / (period * 4);
3206                         printf("%d.%d M/s", speed / 10, speed % 10);
3207                 }
3208                 printf("\n");
3209         }
3210         return 0;
3211 }
3212
3213 static int
3214 scsi_low_wide(struct scsi_low_softc *slp)
3215 {
3216         struct targ_info *ti = slp->sl_Tnexus;
3217         int error;
3218
3219         ti->ti_width = MSGIN_WIDTHP(ti);
3220         error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3221         if (error != 0)
3222         {
3223                 /* XXX:
3224                  * Current width is not acceptable for our adapter.
3225                  * The adapter changes max width.
3226                  */
3227                 printf("%s: wide neg failed. retry wide msg neg ...\n",
3228                         slp->sl_xname);
3229                 return error;
3230         }
3231
3232         ti->ti_owidth = ti->ti_width;
3233         if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3234         {
3235                 ti->ti_setup_msg_done |= 
3236                         (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3237         }
3238                 
3239         /* inform data */
3240         if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3241         {
3242 #ifdef  SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3243                 struct slccb *cb = slp->sl_Qnexus;
3244
3245                 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3246                         return 0;
3247 #endif  /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3248
3249                 printf("%s(%d:*): transfer width %d bits\n",
3250                         slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3251         }
3252         return 0;
3253 }
3254
3255 static int
3256 scsi_low_msginfunc_simple_qtag(struct scsi_low_softc *slp)
3257 {
3258         struct targ_info *ti = slp->sl_Tnexus;
3259         scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3260
3261         if (slp->sl_Qnexus != NULL)
3262         {
3263                 if (slp->sl_Qnexus->ccb_tag != etag)
3264                 {
3265                         slp->sl_error |= FATALIO;
3266                         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3267                         SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3268                 }
3269         }
3270         else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3271         {
3272 #ifdef  SCSI_LOW_DEBUG
3273                 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3274                         return 0;
3275 #endif  /* SCSI_LOW_DEBUG */
3276
3277                 slp->sl_error |= FATALIO;
3278                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3279                 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3280         }
3281         return 0;
3282 }
3283
3284 static int
3285 scsi_low_msginfunc_i_wide_residue(struct scsi_low_softc *slp)
3286 {
3287         struct targ_info *ti = slp->sl_Tnexus;
3288         struct slccb *cb = slp->sl_Qnexus;
3289         int res = (int) ti->ti_msgin[1];
3290
3291         if (cb == NULL || res <= 0 ||
3292             (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3293             (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3294                 return EINVAL;
3295                 
3296         if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3297                 return EINVAL;
3298
3299         slp->sl_scp.scp_datalen += res;
3300         slp->sl_scp.scp_data -= res;
3301         scsi_low_data_finish(slp);
3302         return 0;
3303 }
3304
3305 static int
3306 scsi_low_msginfunc_ext(struct scsi_low_softc *slp)
3307 {
3308         struct slccb *cb = slp->sl_Qnexus;
3309         struct lun_info *li = slp->sl_Lnexus;
3310         struct targ_info *ti = slp->sl_Tnexus;
3311         int count, retry;
3312         u_int32_t *ptr;
3313
3314         if (ti->ti_msginptr == 2)
3315         {
3316                 ti->ti_msginlen = ti->ti_msgin[1] + 2;
3317                 return 0;
3318         }
3319
3320         switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
3321         {
3322         case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
3323                 if (cb == NULL)
3324                         break;
3325
3326                 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
3327                 count = (int) htonl((long) (*ptr));
3328                 if(slp->sl_scp.scp_datalen - count < 0 || 
3329                    slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
3330                         break;
3331
3332                 slp->sl_scp.scp_datalen -= count;
3333                 slp->sl_scp.scp_data += count;
3334                 return 0;
3335
3336         case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
3337                 if (li == NULL)
3338                         break;
3339
3340                 retry = scsi_low_synch(slp);
3341                 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
3342                         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
3343
3344 #ifdef  SCSI_LOW_DEBUG
3345                 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3346                 {
3347                         scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
3348                 }
3349 #endif  /* SCSI_LOW_DEBUG */
3350                 return 0;
3351
3352         case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
3353                 if (li == NULL)
3354                         break;
3355
3356                 retry = scsi_low_wide(slp);
3357                 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
3358                         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
3359
3360                 return 0;
3361
3362         default:
3363                 break;
3364         }
3365
3366         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3367         return EINVAL;
3368 }
3369
3370 static int
3371 scsi_low_msginfunc_parity(struct scsi_low_softc *slp)
3372 {
3373         struct targ_info *ti = slp->sl_Tnexus;
3374
3375         /* only I -> T, invalid! */
3376         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3377         return 0;
3378 }
3379
3380 static int
3381 scsi_low_msginfunc_msg_reject(struct scsi_low_softc *slp)
3382 {
3383         struct targ_info *ti = slp->sl_Tnexus;
3384         struct scsi_low_msgout_data *mdp;
3385         u_int msgflags;
3386
3387         if (ti->ti_emsgflags != 0)
3388         {
3389                 printf("%s: msg flags [0x%x] rejected\n",
3390                        slp->sl_xname, ti->ti_emsgflags);
3391                 msgflags = SCSI_LOW_MSG_REJECT;
3392                 mdp = &scsi_low_msgout_data[0];
3393                 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3394                 {
3395                         if ((ti->ti_emsgflags & mdp->md_flags) != 0)
3396                         {
3397                                 ti->ti_emsgflags &= ~mdp->md_flags;
3398                                 if (mdp->md_errfunc != NULL)
3399                                         (*mdp->md_errfunc) (slp, msgflags);
3400                                 break;
3401                         }
3402                 }
3403                 return 0;
3404         }
3405         else
3406         {
3407                 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
3408                 slp->sl_error |= MSGERR;
3409         }
3410         return EINVAL;
3411 }
3412
3413 int
3414 scsi_low_msgin(struct scsi_low_softc *slp, struct targ_info *ti, u_int c)
3415 {
3416         struct scsi_low_msgin_data *sdp;
3417         struct lun_info *li;
3418         u_int8_t msg;
3419
3420 #ifdef  SCSI_LOW_DIAGNOSTIC
3421         if (ti != slp->sl_Tnexus)
3422         {
3423                 scsi_low_print(slp, NULL);
3424                 panic("scsi_low_msgin: Target nexus inconsistent");
3425         }
3426 #endif  /* SCSI_LOW_DIAGNOSTIC */
3427
3428         /*
3429          * Phase changes, clear the pointer.
3430          */
3431         if (ti->ti_ophase != ti->ti_phase)
3432         {
3433                 MSGINPTR_CLR(ti);
3434                 ti->ti_msgin_parity_error = 0;
3435
3436                 slp->sl_ph_count ++;
3437                 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3438                 {
3439                         printf("%s: too many phase changes\n", slp->sl_xname);
3440                         slp->sl_error |= FATALIO;
3441                         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3442                 }
3443         }
3444
3445         /*
3446          * Store a current messages byte into buffer and 
3447          * wait for the completion of the current msg.
3448          */
3449         ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
3450         if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
3451         {
3452                 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
3453                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3454         }       
3455
3456         /*
3457          * Check parity errors.
3458          */
3459         if ((c & SCSI_LOW_DATA_PE) != 0)
3460         {
3461                 ti->ti_msgin_parity_error ++;
3462                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
3463                 goto out;
3464         }
3465
3466         if (ti->ti_msgin_parity_error != 0)
3467                 goto out;
3468
3469         /*
3470          * Calculate messages length.
3471          */
3472         msg = ti->ti_msgin[0];
3473         if (msg < MSGIN_DATA_LAST)
3474                 sdp = &scsi_low_msgin_data[msg];
3475         else
3476                 sdp = &scsi_low_msgin_data[MSGIN_DATA_LAST];
3477
3478         if (ti->ti_msginlen == 0)
3479         {
3480                 ti->ti_msginlen = sdp->md_len;
3481         }
3482
3483         /*
3484          * Check comletion.
3485          */
3486         if (ti->ti_msginptr < ti->ti_msginlen)
3487                 return EJUSTRETURN;
3488
3489         /*
3490          * Do process.
3491          */
3492         if ((msg & MSG_IDENTIFY) == 0)
3493         {
3494                 if (((*sdp->md_msgfunc) (slp)) == EJUSTRETURN)
3495                         return EJUSTRETURN;
3496         }
3497         else
3498         {
3499                 li = slp->sl_Lnexus;
3500                 if (li == NULL)
3501                 {
3502                         li = scsi_low_alloc_li(ti, MSGCMD_LUN(msg), 0);
3503                         if (li == NULL)
3504                                 goto badlun;
3505                         slp->sl_Lnexus = li;
3506                         (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3507                 }       
3508                 else
3509                 {
3510                         if (MSGCMD_LUN(msg) != li->li_lun)
3511                                 goto badlun;
3512                 }
3513
3514                 if (slp->sl_Qnexus == NULL && li->li_nqio == 0)
3515                 {
3516                         if (!scsi_low_establish_ccb(ti, li, SCSI_LOW_UNKTAG))
3517                         {
3518 #ifdef  SCSI_LOW_DEBUG
3519                                 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3520                                 {
3521                                         goto out;
3522                                 }
3523 #endif  /* SCSI_LOW_DEBUG */
3524                                 goto badlun;
3525                         }
3526                 }
3527         }
3528         goto out;
3529
3530         /*
3531          * Msg process completed, reset msgin pointer and assert ATN if desired.
3532          */
3533 badlun:
3534         slp->sl_error |= FATALIO;
3535         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3536         SCSI_LOW_INFO(slp, ti, "MSGIN: identify wrong");
3537
3538 out:
3539         if (ti->ti_msginptr < ti->ti_msginlen)
3540                 return EJUSTRETURN;
3541
3542 #ifdef  SCSI_LOW_DIAGNOSTIC
3543         scsi_low_msg_log_write(&ti->ti_log_msgin,
3544                                &ti->ti_msgin[0], ti->ti_msginlen);
3545 #endif  /* SCSI_LOW_DIAGNOSTIC */
3546
3547         MSGINPTR_CLR(ti);
3548         return 0;
3549 }
3550
3551 /**********************************************************
3552  * disconnect
3553  **********************************************************/
3554 int
3555 scsi_low_disconnected(struct scsi_low_softc *slp, struct targ_info *ti)
3556 {
3557         struct slccb *cb = slp->sl_Qnexus;
3558
3559         /* check phase completion */
3560         switch (slp->sl_msgphase)
3561         {
3562         case MSGPH_RESET:
3563                 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3564                 scsi_low_msginfunc_cc(slp);
3565                 scsi_low_reset_nexus_target(slp, slp->sl_Tnexus, 0);
3566                 goto io_resume;
3567
3568         case MSGPH_ABORT:
3569                 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3570                 scsi_low_msginfunc_cc(slp);
3571                 scsi_low_reset_nexus_lun(slp, slp->sl_Lnexus, 0);
3572                 goto io_resume;
3573
3574         case MSGPH_TERM:
3575                 scsi_low_statusin(slp, slp->sl_Tnexus, ST_GOOD);
3576                 scsi_low_msginfunc_cc(slp);
3577                 goto io_resume;
3578
3579         case MSGPH_DISC:
3580                 if (cb != NULL)
3581                 {
3582                         struct lun_info *li;
3583
3584                         li = cb->li;
3585                         TAILQ_INSERT_TAIL(&li->li_discq, cb, ccb_chain);
3586                         cb->ccb_flags |= CCB_DISCQ;
3587                         cb->ccb_error |= slp->sl_error;
3588                         li->li_disc ++;
3589                         ti->ti_disc ++;
3590                         slp->sl_disc ++;
3591                 }
3592
3593 #ifdef  SCSI_LOW_STATICS
3594                 scsi_low_statics.nexus_disconnected ++;
3595 #endif  /* SCSI_LOW_STATICS */
3596
3597 #ifdef  SCSI_LOW_DEBUG
3598                 if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DISC, ti->ti_id) != 0)
3599                 {
3600                         printf("## SCSI_LOW_DISCONNECTED ===============\n");
3601                         scsi_low_print(slp, NULL);
3602                 }
3603 #endif  /* SCSI_LOW_DEBUG */
3604                 break;
3605
3606         case MSGPH_NULL:
3607                 slp->sl_error |= FATALIO;
3608                 if (ti->ti_phase == PH_SELSTART)
3609                         slp->sl_error |= SELTIMEOUTIO;
3610                 else
3611                         slp->sl_error |= UBFERR;
3612                 /* fall through */
3613
3614         case MSGPH_LCTERM:
3615         case MSGPH_CMDC:
3616 io_resume:
3617                 if (cb == NULL)
3618                         break;
3619
3620 #ifdef  SCSI_LOW_DEBUG
3621                 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
3622                 {
3623                         if (cb->ccb_omsgoutflag == SCSI_LOW_MSG_NOOP &&
3624                             (cb->ccb_msgoutflag != 0 ||
3625                              (ti->ti_msgflags & SCSI_LOW_MSG_NOOP)))
3626                         {
3627                                 scsi_low_info(slp, ti, "ATTEN CHECK FAILED");
3628                         }
3629                 }
3630 #endif  /* SCSI_LOW_DEBUG */
3631
3632                 cb->ccb_error |= slp->sl_error;
3633                 if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3634                 {
3635                         cb->ccb_flags |= CCB_STARTQ;
3636                         TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
3637                 }
3638                 break;
3639         }
3640
3641         scsi_low_bus_release(slp, ti);  
3642         scsi_low_start(slp);
3643         return 1;
3644 }
3645
3646 /**********************************************************
3647  * TAG operations
3648  **********************************************************/
3649 int
3650 scsi_low_alloc_qtag(struct slccb *cb)
3651 {
3652         struct lun_info *li = cb->li;
3653         scsi_low_tag_t etag;
3654
3655         if (cb->ccb_otag != SCSI_LOW_UNKTAG)
3656                 return 0;
3657
3658 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3659         etag = ffs(li->li_qtagbits);
3660         if (etag == 0)
3661                 return ENOSPC;
3662
3663         li->li_qtagbits &= ~(1 << (etag - 1));
3664         cb->ccb_otag = etag;
3665         return 0;
3666
3667 #else   /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3668         for (etag = li->li_qd ; li->li_qd < SCSI_LOW_MAXNEXUS; li->li_qd ++)
3669                 if (li->li_qtagarray[li->li_qd] == 0)
3670                         goto found;
3671
3672         for (li->li_qd = 0; li->li_qd < etag; li->li_qd ++)
3673                 if (li->li_qtagarray[li->li_qd] == 0)
3674                         goto found;
3675
3676         return ENOSPC;
3677
3678 found:
3679         li->li_qtagarray[li->li_qd] ++;
3680         cb->ccb_otag = (li->li_qd ++);
3681         return 0;
3682 #endif  /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3683 }
3684         
3685 int
3686 scsi_low_dealloc_qtag(struct slccb *cb)
3687 {
3688         struct lun_info *li = cb->li;
3689         scsi_low_tag_t etag;
3690
3691         if (cb->ccb_otag == SCSI_LOW_UNKTAG)
3692                 return 0;
3693
3694 #ifndef SCSI_LOW_ALT_QTAG_ALLOCATE
3695         etag = cb->ccb_otag - 1;
3696 #ifdef  SCSI_LOW_DIAGNOSTIC
3697         if (etag >= sizeof(li->li_qtagbits) * NBBY)
3698                 panic("scsi_low_dealloc_tag: illegal tag");
3699 #endif  /* SCSI_LOW_DIAGNOSTIC */
3700         li->li_qtagbits |= (1 << etag);
3701
3702 #else   /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3703         etag = cb->ccb_otag;
3704 #ifdef  SCSI_LOW_DIAGNOSTIC
3705         if (etag >= SCSI_LOW_MAXNEXUS)
3706                 panic("scsi_low_dealloc_tag: illegal tag");
3707 #endif  /* SCSI_LOW_DIAGNOSTIC */
3708         li->li_qtagarray[etag] --;
3709 #endif  /* SCSI_LOW_ALT_QTAG_ALLOCATE */
3710
3711         cb->ccb_otag = SCSI_LOW_UNKTAG;
3712         return 0;
3713 }
3714
3715 struct slccb *
3716 scsi_low_revoke_ccb(struct scsi_low_softc *slp, struct slccb *cb, int fdone)
3717 {
3718         struct targ_info *ti = cb->ti;
3719         struct lun_info *li = cb->li;
3720
3721 #ifdef  SCSI_LOW_DIAGNOSTIC
3722         if ((cb->ccb_flags & (CCB_STARTQ | CCB_DISCQ)) == 
3723             (CCB_STARTQ | CCB_DISCQ))
3724         {
3725                 panic("%s: ccb in both queue", slp->sl_xname);
3726         }
3727 #endif  /* SCSI_LOW_DIAGNOSTIC */
3728
3729         if ((cb->ccb_flags & CCB_STARTQ) != 0)
3730         {
3731                 TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
3732         }
3733
3734         if ((cb->ccb_flags & CCB_DISCQ) != 0)
3735         {
3736                 TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3737                 li->li_disc --;
3738                 ti->ti_disc --;
3739                 slp->sl_disc --;
3740         }
3741
3742         cb->ccb_flags &= ~(CCB_STARTQ | CCB_DISCQ | 
3743                            CCB_SENSE | CCB_CLEARQ | CCB_INTERNAL);
3744
3745         if (fdone != 0 &&
3746             (cb->ccb_rcnt ++ >= slp->sl_max_retry || 
3747              (cb->ccb_flags & CCB_NORETRY) != 0))
3748         {
3749                 cb->ccb_error |= FATALIO;
3750                 cb->ccb_flags &= ~CCB_AUTOSENSE;
3751                 if (scsi_low_done(slp, cb) != SCSI_LOW_DONE_COMPLETE)
3752                         panic("%s: done ccb retried", slp->sl_xname);
3753                 return NULL;
3754         }
3755         else
3756         {
3757                 cb->ccb_error |= PENDINGIO;
3758                 scsi_low_deactivate_qtag(cb);
3759                 scsi_low_ccb_message_retry(cb);
3760                 cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3761                 return cb;
3762         }
3763 }
3764
3765 void
3766 scsi_low_reset_nexus_lun(struct scsi_low_softc *slp, struct lun_info *li, int fdone)
3767 {
3768         struct slccb *cb, *ncb, *ecb;
3769
3770         if (li == NULL)
3771                 return;
3772
3773         ecb = NULL;
3774         for (cb = TAILQ_FIRST(&li->li_discq); cb != NULL; cb = ncb)
3775         {
3776                 ncb = TAILQ_NEXT(cb, ccb_chain);
3777                 cb = scsi_low_revoke_ccb(slp, cb, fdone);
3778                 if (cb != NULL)
3779                 {
3780                         /*
3781                          * presumely keep ordering of io
3782                          */
3783                         cb->ccb_flags |= CCB_STARTQ;
3784                         if (ecb == NULL)
3785                         {
3786                                 TAILQ_INSERT_HEAD(&slp->sl_start,\
3787                                                   cb, ccb_chain);
3788                         }
3789                         else
3790                         {
3791                                 TAILQ_INSERT_AFTER(&slp->sl_start,\
3792                                                    ecb, cb, ccb_chain);
3793                         }
3794                         ecb = cb;
3795                 }
3796         }
3797 }
3798         
3799 /**************************************************************
3800  * Qurik setup
3801  **************************************************************/
3802 static void
3803 scsi_low_calcf_lun(struct lun_info *li)
3804 {
3805         struct targ_info *ti = li->li_ti;
3806         struct scsi_low_softc *slp = ti->ti_sc;
3807         u_int cfgflags, diskflags;
3808
3809         if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID)
3810                 cfgflags = li->li_cfgflags;
3811         else
3812                 cfgflags = 0;
3813
3814         diskflags = li->li_diskflags & li->li_quirks;
3815
3816         /* disconnect */
3817         li->li_flags &= ~SCSI_LOW_DISC;
3818         if ((slp->sl_cfgflags & CFG_NODISC) == 0 &&
3819             (diskflags & SCSI_LOW_DISK_DISC) != 0 &&
3820             (cfgflags & SCSI_LOW_DISC) != 0)
3821                 li->li_flags |= SCSI_LOW_DISC;
3822
3823         /* parity */
3824         li->li_flags |= SCSI_LOW_NOPARITY;
3825         if ((slp->sl_cfgflags & CFG_NOPARITY) == 0 &&
3826             (diskflags & SCSI_LOW_DISK_PARITY) != 0 &&
3827             (cfgflags & SCSI_LOW_NOPARITY) == 0)
3828                 li->li_flags &= ~SCSI_LOW_NOPARITY;
3829
3830         /* qtag */
3831         if ((slp->sl_cfgflags & CFG_NOQTAG) == 0 &&
3832             (cfgflags & SCSI_LOW_QTAG) != 0 &&
3833             (diskflags & SCSI_LOW_DISK_QTAG) != 0)
3834         {
3835                 li->li_flags |= SCSI_LOW_QTAG;
3836                 li->li_maxnexus = SCSI_LOW_MAXNEXUS;
3837                 li->li_maxnqio = li->li_maxnexus;
3838         }
3839         else
3840         {
3841                 li->li_flags &= ~SCSI_LOW_QTAG;
3842                 li->li_maxnexus = 0;
3843                 li->li_maxnqio = li->li_maxnexus;
3844         }
3845
3846         /* cmd link */
3847         li->li_flags &= ~SCSI_LOW_LINK;
3848         if ((cfgflags & SCSI_LOW_LINK) != 0 &&
3849             (diskflags & SCSI_LOW_DISK_LINK) != 0)
3850                 li->li_flags |= SCSI_LOW_LINK;
3851
3852         /* compatible flags */
3853         li->li_flags &= ~SCSI_LOW_SYNC;
3854         if (ti->ti_maxsynch.offset > 0)
3855                 li->li_flags |= SCSI_LOW_SYNC;
3856
3857 #ifdef  SCSI_LOW_DEBUG
3858         if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3859         {
3860                 scsi_low_calcf_show(li);
3861         }
3862 #endif  /* SCSI_LOW_DEBUG */
3863 }
3864
3865 static void
3866 scsi_low_calcf_target(struct targ_info *ti)
3867 {
3868         struct scsi_low_softc *slp = ti->ti_sc;
3869         u_int offset, period, diskflags;
3870
3871         diskflags = ti->ti_diskflags & ti->ti_quirks;
3872
3873         /* synch */
3874         if ((slp->sl_cfgflags & CFG_ASYNC) == 0 &&
3875             (diskflags & SCSI_LOW_DISK_SYNC) != 0)
3876         {
3877                 offset = ti->ti_maxsynch.offset;
3878                 period = ti->ti_maxsynch.period;
3879                 if (offset == 0 || period == 0)
3880                         offset = period = 0;
3881         }
3882         else
3883         {
3884                 offset = period = 0;
3885         }
3886         
3887         ti->ti_maxsynch.offset = offset;
3888         ti->ti_maxsynch.period = period;
3889
3890         /* wide */
3891         if ((diskflags & SCSI_LOW_DISK_WIDE_32) == 0 &&
3892              ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
3893                 ti->ti_width = SCSI_LOW_BUS_WIDTH_16;
3894
3895         if ((diskflags & SCSI_LOW_DISK_WIDE_16) == 0 &&
3896             ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3897                 ti->ti_width = SCSI_LOW_BUS_WIDTH_8;
3898
3899         if (ti->ti_flags_valid == SCSI_LOW_TARG_FLAGS_ALL_VALID)
3900         {
3901                 if (ti->ti_maxsynch.offset != ti->ti_osynch.offset ||
3902                     ti->ti_maxsynch.period != ti->ti_osynch.period)
3903                         ti->ti_setup_msg |= SCSI_LOW_MSG_SYNCH;
3904                 if (ti->ti_width != ti->ti_owidth)
3905                         ti->ti_setup_msg |= (SCSI_LOW_MSG_WIDE | SCSI_LOW_MSG_SYNCH);
3906
3907                 ti->ti_osynch = ti->ti_maxsynch;
3908                 ti->ti_owidth = ti->ti_width;
3909         }
3910
3911 #ifdef  SCSI_LOW_DEBUG
3912         if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_CALCF, ti->ti_id) != 0)
3913         {
3914                 printf("%s(%d:*): max period(%dns) offset(%d) width(%d)\n",
3915                         slp->sl_xname, ti->ti_id,
3916                         ti->ti_maxsynch.period * 4,
3917                         ti->ti_maxsynch.offset,
3918                         ti->ti_width);
3919         }
3920 #endif  /* SCSI_LOW_DEBUG */
3921 }
3922
3923 static void
3924 scsi_low_calcf_show(struct lun_info *li)
3925 {
3926         struct targ_info *ti = li->li_ti;
3927         struct scsi_low_softc *slp = ti->ti_sc;
3928
3929         printf("%s(%d:%d): period(%d ns) offset(%d) width(%d) flags 0x%b\n",
3930                 slp->sl_xname, ti->ti_id, li->li_lun,
3931                 ti->ti_maxsynch.period * 4,
3932                 ti->ti_maxsynch.offset,
3933                 ti->ti_width,
3934                 li->li_flags, SCSI_LOW_BITS);
3935 }
3936
3937 #ifdef  SCSI_LOW_START_UP_CHECK
3938 /**************************************************************
3939  * scsi world start up
3940  **************************************************************/
3941 static int scsi_low_poll (struct scsi_low_softc *, struct slccb *);
3942
3943 static int
3944 scsi_low_start_up(struct scsi_low_softc *slp)
3945 {
3946         struct targ_info *ti;
3947         struct lun_info *li;
3948         struct slccb *cb;
3949         int target, lun;
3950
3951         printf("%s: scsi_low: probing all devices ....\n", slp->sl_xname);
3952
3953         for (target = 0; target < slp->sl_ntargs; target ++)
3954         {
3955                 if (target == slp->sl_hostid)
3956                 {
3957                         if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3958                         {
3959                                 printf("%s: scsi_low: target %d (host card)\n",
3960                                         slp->sl_xname, target);
3961                         }
3962                         continue;
3963                 }
3964
3965                 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3966                 {
3967                         printf("%s: scsi_low: target %d lun ",
3968                                 slp->sl_xname, target);
3969                 }
3970
3971                 ti = slp->sl_ti[target];
3972                 for (lun = 0; lun < slp->sl_nluns; lun ++)
3973                 {
3974                         if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
3975                                 break;
3976
3977                         cb->osdep = NULL;
3978                         cb->bp = NULL;
3979
3980                         li = scsi_low_alloc_li(ti, lun, 1);
3981
3982                         scsi_low_enqueue(slp, ti, li, cb,
3983                                          CCB_AUTOSENSE | CCB_POLLED, 0);
3984
3985                         scsi_low_poll(slp, cb);
3986
3987                         if (li->li_state != SCSI_LOW_LUN_OK)
3988                                 break;
3989
3990                         if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3991                         {
3992                                 printf("%d ", lun);             
3993                         }
3994                 }
3995
3996                 if ((slp->sl_show_result & SHOW_PROBE_RES) != 0)
3997                 {
3998                         printf("\n");
3999                 }
4000         }
4001         return 0;
4002 }
4003
4004 static int
4005 scsi_low_poll(struct scsi_low_softc *slp, struct slccb *cb)
4006 {
4007         int tcount;
4008
4009         tcount = 0;
4010         while (slp->sl_nio > 0)
4011         {
4012                 SCSI_LOW_DELAY((1000 * 1000) / SCSI_LOW_POLL_HZ);
4013
4014                 (*slp->sl_funcs->scsi_low_poll) (slp);
4015                 if (tcount ++ < SCSI_LOW_POLL_HZ / SCSI_LOW_TIMEOUT_HZ)
4016                         continue;
4017
4018                 tcount = 0;
4019                 scsi_low_timeout_check(slp);
4020         }
4021
4022         return 0;
4023 }
4024 #endif  /* SCSI_LOW_START_UP_CHECK */
4025
4026 /**********************************************************
4027  * DEBUG SECTION
4028  **********************************************************/
4029 #ifdef  SCSI_LOW_DEBUG
4030 static void
4031 scsi_low_test_abort(struct scsi_low_softc *slp, struct targ_info *ti,
4032                     struct lun_info *li)
4033 {
4034         struct slccb *acb;
4035
4036         if (li->li_disc > 1)
4037         {
4038                 acb = TAILQ_FIRST(&li->li_discq); 
4039                 if (scsi_low_abort_ccb(slp, acb) == 0)
4040                 {
4041                         printf("%s: aborting ccb(0x%lx) start\n",
4042                                 slp->sl_xname, (u_long) acb);
4043                 }
4044         }
4045 }
4046
4047 static void
4048 scsi_low_test_atten(struct scsi_low_softc *slp, struct targ_info *ti, u_int msg)
4049 {
4050         if (slp->sl_ph_count < SCSI_LOW_MAX_ATTEN_CHECK)
4051                 scsi_low_assert_msg(slp, ti, msg, 0);
4052         else
4053                 printf("%s: atten check OK\n", slp->sl_xname);
4054 }
4055
4056 static void
4057 scsi_low_test_cmdlnk(struct scsi_low_softc *slp, struct slccb *cb)
4058 {
4059 #define SCSI_LOW_CMDLNK_NOK     (CCB_INTERNAL | CCB_SENSE | CCB_CLEARQ)
4060
4061         if ((cb->ccb_flags & SCSI_LOW_CMDLNK_NOK) != 0)
4062                 return;
4063
4064         memcpy(cb->ccb_scsi_cmd, slp->sl_scp.scp_cmd,
4065                slp->sl_scp.scp_cmdlen);
4066         cb->ccb_scsi_cmd[slp->sl_scp.scp_cmdlen - 1] |= 1;
4067         slp->sl_scp.scp_cmd = cb->ccb_scsi_cmd;
4068 }
4069 #endif  /* SCSI_LOW_DEBUG */
4070
4071 /* static */ void
4072 scsi_low_info(struct scsi_low_softc *slp, struct targ_info *ti, u_char *s)
4073 {
4074         if (slp == NULL)
4075                 slp = LIST_FIRST(&sl_tab);
4076         if (s == NULL)
4077                 s = "no message";
4078
4079         printf(">>>>> SCSI_LOW_INFO(0x%lx): %s\n", (u_long) slp->sl_Tnexus, s);
4080         if (ti == NULL)
4081         {
4082                 for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
4083                      ti = TAILQ_NEXT(ti, ti_chain))
4084                 {
4085                         scsi_low_print(slp, ti);
4086                 }