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