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