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