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