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