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