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