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