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