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