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