Merge from vendor branch BINUTILS:
[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.6 2003/12/29 23:31:00 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                 cam_calc_geometry(&ccb->ccg, /*extended*/1);
1289                 xpt_done(ccb);
1290                 break;
1291         }
1292
1293         case XPT_RESET_BUS:             /* Reset the specified SCSI bus */
1294                 s = SCSI_LOW_SPLSCSI();
1295                 scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL);
1296                 splx(s);
1297                 ccb->ccb_h.status = CAM_REQ_CMP;
1298                 xpt_done(ccb);
1299                 break;
1300
1301         case XPT_TERM_IO:       /* Terminate the I/O process */
1302                 ccb->ccb_h.status = CAM_REQ_INVALID;
1303                 xpt_done(ccb);
1304                 break;
1305
1306         case XPT_RESET_DEV:     /* Bus Device Reset the specified SCSI device */
1307 #ifdef  SCSI_LOW_DIAGNOSTIC
1308                 if (target == CAM_TARGET_WILDCARD)
1309                 {
1310                         printf("%s: invalid target\n", slp->sl_xname);
1311                         ccb->ccb_h.status = CAM_REQ_INVALID;
1312                         xpt_done(ccb);
1313                         return;
1314                 }
1315 #endif  /* SCSI_LOW_DIAGNOSTIC */
1316
1317                 msg = SCSI_LOW_MSG_RESET;
1318                 if (((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL))
1319                 {
1320                         ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
1321                         xpt_done(ccb);
1322                         return;
1323                 }
1324
1325                 ti = slp->sl_ti[target];
1326                 if (lun == CAM_LUN_WILDCARD)
1327                         lun = 0;
1328                 cb->osdep = ccb;
1329                 cb->bp = NULL;
1330                 if ((ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)
1331                         flags = CCB_AUTOSENSE | CCB_NORETRY | CCB_URGENT;
1332                 else
1333                         flags = CCB_NORETRY | CCB_URGENT;
1334
1335                 s = SCSI_LOW_SPLSCSI();
1336                 li = scsi_low_alloc_li(ti, lun, 1);
1337                 scsi_low_enqueue(slp, ti, li, cb, flags, msg);
1338                 splx(s);
1339                 break;
1340
1341         case XPT_PATH_INQ: {            /* Path routing inquiry */
1342                 struct ccb_pathinq *cpi = &ccb->cpi;
1343                 
1344                 cpi->version_num = scsi_low_version_major;
1345                 cpi->hba_inquiry = PI_TAG_ABLE | PI_LINKED_CDB;
1346                 ti = slp->sl_ti[slp->sl_hostid];        /* host id */
1347                 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
1348                         cpi->hba_inquiry |= PI_WIDE_16;
1349                 if (ti->ti_width > SCSI_LOW_BUS_WIDTH_16)
1350                         cpi->hba_inquiry |= PI_WIDE_32;
1351                 if (ti->ti_maxsynch.offset > 0)
1352                         cpi->hba_inquiry |= PI_SDTR_ABLE;
1353                 cpi->target_sprt = 0;
1354                 cpi->hba_misc = 0;
1355                 cpi->hba_eng_cnt = 0;
1356                 cpi->max_target = slp->sl_ntargs - 1;
1357                 cpi->max_lun = slp->sl_nluns - 1;
1358                 cpi->initiator_id = slp->sl_hostid;
1359                 cpi->bus_id = cam_sim_bus(sim);
1360                 cpi->base_transfer_speed = 3300;
1361 #ifdef CAM_NEW_TRAN_CODE
1362                 cpi->transport = XPORT_SPI;
1363                 cpi->transport_version = 2;
1364                 cpi->protocol = PROTO_SCSI;
1365                 cpi->protocol_version = SCSI_REV_2;
1366 #endif
1367                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
1368                 strncpy(cpi->hba_vid, "SCSI_LOW", HBA_IDLEN);
1369                 strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
1370                 cpi->unit_number = cam_sim_unit(sim);
1371                 cpi->ccb_h.status = CAM_REQ_CMP;
1372                 xpt_done(ccb);
1373                 break;
1374         }
1375
1376         default:
1377                 printf("scsi_low: non support func_code = %d ",
1378                         ccb->ccb_h.func_code);
1379                 ccb->ccb_h.status = CAM_REQ_INVALID;
1380                 xpt_done(ccb);
1381                 break;
1382         }
1383 }
1384
1385 static int
1386 scsi_low_attach_cam(slp)
1387         struct scsi_low_softc *slp;
1388 {
1389         struct cam_devq *devq;
1390         int tagged_openings;
1391
1392         sprintf(slp->sl_xname, "%s%d",
1393                 DEVPORT_DEVNAME(slp->sl_dev), DEVPORT_DEVUNIT(slp->sl_dev));
1394
1395         devq = cam_simq_alloc(SCSI_LOW_NCCB);
1396         if (devq == NULL)
1397                 return (ENOMEM);
1398
1399         /*
1400          * ask the adapter what subunits are present
1401          */
1402         tagged_openings = min(slp->sl_openings, SCSI_LOW_MAXNEXUS);
1403         slp->sl_si.sim = cam_sim_alloc(scsi_low_scsi_action_cam,
1404                                 scsi_low_poll_cam,
1405                                 DEVPORT_DEVNAME(slp->sl_dev), slp,
1406                                 DEVPORT_DEVUNIT(slp->sl_dev), 
1407                                 slp->sl_openings, tagged_openings, devq);
1408
1409         if (slp->sl_si.sim == NULL) {
1410                 cam_simq_free(devq);
1411                 return ENODEV;
1412         }
1413
1414         if (xpt_bus_register(slp->sl_si.sim, 0) != CAM_SUCCESS) {
1415                 free(slp->sl_si.sim, M_DEVBUF);
1416                 return ENODEV;
1417         }
1418        
1419         if (xpt_create_path(&slp->sl_si.path, /*periph*/NULL,
1420                         cam_sim_path(slp->sl_si.sim), CAM_TARGET_WILDCARD,
1421                         CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1422                 xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1423                 cam_sim_free(slp->sl_si.sim, /*free_simq*/TRUE);
1424                 free(slp->sl_si.sim, M_DEVBUF);
1425                 return ENODEV;
1426         }
1427
1428         slp->sl_show_result = SHOW_CALCF_RES;           /* OK ? */
1429         return 0;
1430 }
1431
1432 static int
1433 scsi_low_world_start_cam(slp)
1434         struct scsi_low_softc *slp;
1435 {
1436
1437         if (!cold)
1438                 scsi_low_rescan_bus_cam(slp);
1439         return 0;
1440 }
1441
1442 static int
1443 scsi_low_dettach_cam(slp)
1444         struct scsi_low_softc *slp;
1445 {
1446
1447         xpt_async(AC_LOST_DEVICE, slp->sl_si.path, NULL);
1448         xpt_free_path(slp->sl_si.path);
1449         xpt_bus_deregister(cam_sim_path(slp->sl_si.sim));
1450         cam_sim_free(slp->sl_si.sim, /* free_devq */ TRUE);
1451         return 0;
1452 }
1453
1454 static int
1455 scsi_low_ccb_setup_cam(slp, cb)
1456         struct scsi_low_softc *slp;
1457         struct slccb *cb;
1458 {
1459         union ccb *ccb = (union ccb *) cb->osdep;
1460
1461         if ((cb->ccb_flags & CCB_SCSIIO) != 0)
1462         {
1463                 cb->ccb_scp.scp_cmd = ccb->csio.cdb_io.cdb_bytes;
1464                 cb->ccb_scp.scp_cmdlen = (int) ccb->csio.cdb_len;
1465                 cb->ccb_scp.scp_data = ccb->csio.data_ptr;
1466                 cb->ccb_scp.scp_datalen = (int) ccb->csio.dxfer_len;
1467                 if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_OUT)
1468                         cb->ccb_scp.scp_direction = SCSI_LOW_WRITE;
1469                 else /* if((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) */
1470                         cb->ccb_scp.scp_direction = SCSI_LOW_READ;
1471                 cb->ccb_tcmax = ccb->ccb_h.timeout / 1000;
1472         }
1473         else
1474         {
1475                 scsi_low_unit_ready_cmd(cb);
1476         }
1477         return SCSI_LOW_START_QTAG;
1478 }
1479
1480 static int
1481 scsi_low_done_cam(slp, cb)
1482         struct scsi_low_softc *slp;
1483         struct slccb *cb;
1484 {
1485         union ccb *ccb;
1486
1487         ccb = (union ccb *) cb->osdep;
1488         if (cb->ccb_error == 0)
1489         {
1490                 ccb->ccb_h.status = CAM_REQ_CMP;
1491                 ccb->csio.resid = 0;
1492         }
1493         else    
1494         {
1495                 if (cb->ccb_rcnt >= slp->sl_max_retry)
1496                         cb->ccb_error |= ABORTIO;
1497
1498                 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
1499                     (cb->ccb_error & ABORTIO) == 0)
1500                         return EJUSTRETURN;
1501
1502                 if ((cb->ccb_error & SENSEIO) != 0)
1503                 {
1504                         memcpy(&ccb->csio.sense_data,
1505                                &cb->ccb_sense,
1506                                sizeof(ccb->csio.sense_data));
1507                 }
1508
1509                 ccb->ccb_h.status = scsi_low_translate_error_code(cb,
1510                                         &scsi_low_error_code_cam[0]);
1511         
1512 #ifdef  SCSI_LOW_DIAGNOSTIC
1513                 if ((cb->ccb_flags & CCB_SILENT) == 0 &&
1514                     cb->ccb_scp.scp_cmdlen > 0 &&
1515                     (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
1516                      SCSI_LOW_CMD_ABORT_WARNING) != 0)
1517                 {
1518                         printf("%s: WARNING: scsi_low IO abort\n",
1519                                 slp->sl_xname);
1520                         scsi_low_print(slp, NULL);
1521                 }
1522 #endif  /* SCSI_LOW_DIAGNOSTIC */
1523         }
1524
1525         if ((ccb->ccb_h.status & CAM_STATUS_MASK) == 0)
1526                 ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
1527
1528         if (cb->ccb_scp.scp_status == ST_UNKNOWN)
1529                 ccb->csio.scsi_status = 0;      /* XXX */
1530         else
1531                 ccb->csio.scsi_status = cb->ccb_scp.scp_status;
1532
1533         if ((cb->ccb_flags & CCB_NOSDONE) == 0)
1534                 xpt_done(ccb);
1535         return 0;
1536 }
1537
1538 static void
1539 scsi_low_timeout_cam(slp, ch, action)
1540         struct scsi_low_softc *slp;
1541         int ch;
1542         int action;
1543 {
1544
1545         switch (ch)
1546         {
1547         case SCSI_LOW_TIMEOUT_CH_IO:
1548                 switch (action)
1549                 {
1550                 case SCSI_LOW_TIMEOUT_START:
1551                         slp->sl_si.timeout_ch = timeout(scsi_low_timeout, slp,
1552                                 hz / SCSI_LOW_TIMEOUT_HZ);
1553                         break;
1554                 case SCSI_LOW_TIMEOUT_STOP:
1555                         untimeout(scsi_low_timeout, slp, slp->sl_si.timeout_ch);
1556                         break;
1557                 }
1558                 break;
1559
1560         case SCSI_LOW_TIMEOUT_CH_ENGAGE:
1561                 switch (action)
1562                 {
1563                 case SCSI_LOW_TIMEOUT_START:
1564                         slp->sl_si.engage_ch = timeout(scsi_low_engage, slp, 1);
1565                         break;
1566                 case SCSI_LOW_TIMEOUT_STOP:
1567                         untimeout(scsi_low_engage, slp, slp->sl_si.engage_ch);
1568                         break;
1569                 }
1570                 break;
1571         case SCSI_LOW_TIMEOUT_CH_RECOVER:
1572                 break;
1573         }
1574 }
1575
1576 #endif  /* SCSI_LOW_INTERFACE_CAM */
1577
1578 /*=============================================================
1579  * END OF OS switch  (All OS depend fucntions should be above)
1580  =============================================================*/
1581
1582 /**************************************************************
1583  * scsi low deactivate and activate
1584  **************************************************************/
1585 int
1586 scsi_low_is_busy(slp)
1587         struct scsi_low_softc *slp;
1588 {
1589
1590         if (slp->sl_nio > 0)
1591                 return EBUSY;
1592         return 0;
1593 }
1594
1595 int
1596 scsi_low_deactivate(slp)
1597         struct scsi_low_softc *slp;
1598 {
1599         int s;
1600
1601         s = SCSI_LOW_SPLSCSI();
1602         slp->sl_flags |= HW_INACTIVE;
1603         (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1604                 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_STOP);
1605         (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1606                 (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1607         splx(s);
1608         return 0;
1609 }
1610
1611 int
1612 scsi_low_activate(slp)
1613         struct scsi_low_softc *slp;
1614 {
1615         int error, s;
1616
1617         s = SCSI_LOW_SPLSCSI();
1618         slp->sl_flags &= ~HW_INACTIVE;
1619         if ((error = scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, NULL)) != 0)
1620         {
1621                 slp->sl_flags |= HW_INACTIVE;
1622                 splx(s);
1623                 return error;
1624         }
1625
1626         slp->sl_timeout_count = 0;
1627         (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1628                 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1629         splx(s);
1630         return 0;
1631 }
1632
1633 /**************************************************************
1634  * scsi low log
1635  **************************************************************/
1636 #ifdef  SCSI_LOW_DIAGNOSTIC
1637 static void scsi_low_msg_log_init (struct scsi_low_msg_log *);
1638 static void scsi_low_msg_log_write (struct scsi_low_msg_log *, u_int8_t *,
1639 int);
1640 static void scsi_low_msg_log_show (struct scsi_low_msg_log *, char *, int);
1641
1642 static void
1643 scsi_low_msg_log_init(slmlp)
1644         struct scsi_low_msg_log *slmlp;
1645 {
1646
1647         slmlp->slml_ptr = 0;
1648 }
1649
1650 static void
1651 scsi_low_msg_log_write(slmlp, datap, len)
1652         struct scsi_low_msg_log *slmlp;
1653         u_int8_t *datap;
1654         int len;
1655 {
1656         int ptr, ind;
1657
1658         if (slmlp->slml_ptr >= SCSI_LOW_MSG_LOG_DATALEN)
1659                 return;
1660
1661         ptr = slmlp->slml_ptr ++;
1662         for (ind = 0; ind < sizeof(slmlp->slml_msg[0]) && ind < len; ind ++)
1663                 slmlp->slml_msg[ptr].msg[ind] = datap[ind];
1664         for ( ; ind < sizeof(slmlp->slml_msg[0]); ind ++)
1665                 slmlp->slml_msg[ptr].msg[ind] = 0;
1666 }
1667         
1668 static void
1669 scsi_low_msg_log_show(slmlp, s, len)
1670         struct scsi_low_msg_log *slmlp;
1671         char *s;
1672         int len;
1673 {
1674         int ptr, ind;
1675
1676         printf("%s: (%d) ", s, slmlp->slml_ptr);
1677         for (ptr = 0; ptr < slmlp->slml_ptr; ptr ++)
1678         {
1679                 for (ind = 0; ind < len && ind < sizeof(slmlp->slml_msg[0]);
1680                      ind ++)
1681                 {
1682                         printf("[%x]", (u_int) slmlp->slml_msg[ptr].msg[ind]);
1683                 }
1684                 printf(">");
1685         }
1686         printf("\n");
1687 }
1688 #endif  /* SCSI_LOW_DIAGNOSTIC */
1689
1690 /**************************************************************
1691  * power control
1692  **************************************************************/
1693 static void
1694 scsi_low_engage(arg)
1695         void *arg;
1696 {
1697         struct scsi_low_softc *slp = arg;
1698         int s = SCSI_LOW_SPLSCSI();
1699
1700         switch (slp->sl_rstep)
1701         {
1702         case 0:
1703                 slp->sl_rstep ++;
1704                 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
1705                 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 
1706                         SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_START);
1707                 break;
1708
1709         case 1:
1710                 slp->sl_rstep ++;
1711                 slp->sl_flags &= ~HW_RESUME;
1712                 scsi_low_start(slp);
1713                 break;
1714
1715         case 2:
1716                 break;
1717         }
1718         splx(s);
1719 }
1720
1721 static int
1722 scsi_low_init(slp, flags)
1723         struct scsi_low_softc *slp;
1724         u_int flags;
1725 {
1726         int rv = 0;
1727
1728         slp->sl_flags |= HW_INITIALIZING;
1729
1730         /* clear power control timeout */
1731         if ((slp->sl_flags & HW_POWERCTRL) != 0)
1732         {
1733                 (*slp->sl_osdep_fp->scsi_low_osdep_timeout) (slp, 
1734                         SCSI_LOW_TIMEOUT_CH_ENGAGE, SCSI_LOW_TIMEOUT_STOP);
1735                 slp->sl_flags &= ~(HW_POWDOWN | HW_RESUME);
1736                 slp->sl_active = 1;
1737                 slp->sl_powc = SCSI_LOW_POWDOWN_TC;
1738         }
1739
1740         /* reset current nexus */
1741         scsi_low_reset_nexus(slp, flags);
1742         if ((slp->sl_flags & HW_INACTIVE) != 0)
1743         {
1744                 rv = EBUSY;
1745                 goto out;
1746         }
1747
1748         if (flags != SCSI_LOW_RESTART_SOFT)
1749         {
1750                 rv = ((*slp->sl_funcs->scsi_low_init) (slp, flags));
1751         }
1752
1753 out:
1754         slp->sl_flags &= ~HW_INITIALIZING;
1755         return rv;
1756 }
1757
1758 /**************************************************************
1759  * allocate lun_info
1760  **************************************************************/
1761 static struct lun_info *
1762 scsi_low_alloc_li(ti, lun, alloc)
1763         struct targ_info *ti;
1764         int lun;
1765         int alloc;
1766 {
1767         struct scsi_low_softc *slp = ti->ti_sc;
1768         struct lun_info *li;
1769
1770         li = LIST_FIRST(&ti->ti_litab); 
1771         if (li != NULL)
1772         { 
1773                 if (li->li_lun == lun)
1774                         return li;
1775
1776                 while ((li = LIST_NEXT(li, lun_chain)) != NULL)
1777                 {
1778                         if (li->li_lun == lun)
1779                         {
1780                                 LIST_REMOVE(li, lun_chain);
1781                                 LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1782                                 return li;
1783                         }
1784                 }
1785         }
1786
1787         if (alloc == 0)
1788                 return li;
1789
1790         li = SCSI_LOW_MALLOC(ti->ti_lunsize);
1791         if (li == NULL)
1792                 panic("no lun info mem");
1793
1794         SCSI_LOW_BZERO(li, ti->ti_lunsize);
1795         li->li_lun = lun;
1796         li->li_ti = ti;
1797
1798         li->li_cfgflags = SCSI_LOW_SYNC | SCSI_LOW_LINK | SCSI_LOW_DISC |
1799                           SCSI_LOW_QTAG;
1800         li->li_quirks = li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
1801         li->li_flags_valid = SCSI_LOW_LUN_FLAGS_USER_VALID;
1802 #ifdef  SCSI_LOW_FLAGS_QUIRKS_OK
1803         li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_QUIRKS_VALID;
1804 #endif  /* SCSI_LOW_FLAGS_QUIRKS_OK */
1805
1806         li->li_qtagbits = (u_int) -1;
1807
1808         TAILQ_INIT(&li->li_discq);
1809         LIST_INSERT_HEAD(&ti->ti_litab, li, lun_chain);
1810
1811         /* host specific structure initialization per lun */
1812         if (slp->sl_funcs->scsi_low_lun_init != NULL)
1813                 (*slp->sl_funcs->scsi_low_lun_init)
1814                         (slp, ti, li, SCSI_LOW_INFO_ALLOC);
1815         scsi_low_calcf_lun(li);
1816         return li;
1817 }
1818
1819 /**************************************************************
1820  * allocate targ_info
1821  **************************************************************/
1822 static struct targ_info *
1823 scsi_low_alloc_ti(slp, targ)
1824         struct scsi_low_softc *slp;
1825         int targ;
1826 {
1827         struct targ_info *ti;
1828
1829         if (TAILQ_FIRST(&slp->sl_titab) == NULL)
1830                 TAILQ_INIT(&slp->sl_titab);
1831
1832         ti = SCSI_LOW_MALLOC(slp->sl_targsize);
1833         if (ti == NULL)
1834                 panic("%s short of memory", slp->sl_xname);
1835
1836         SCSI_LOW_BZERO(ti, slp->sl_targsize);
1837         ti->ti_id = targ;
1838         ti->ti_sc = slp;
1839
1840         slp->sl_ti[targ] = ti;
1841         TAILQ_INSERT_TAIL(&slp->sl_titab, ti, ti_chain);
1842         LIST_INIT(&ti->ti_litab);
1843
1844         ti->ti_quirks = ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
1845         ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
1846         ti->ti_flags_valid = SCSI_LOW_TARG_FLAGS_USER_VALID;
1847 #ifdef  SCSI_LOW_FLAGS_QUIRKS_OK
1848         ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_QUIRKS_VALID;
1849 #endif  /* SCSI_LOW_FLAGS_QUIRKS_OK */
1850
1851         if (slp->sl_funcs->scsi_low_targ_init != NULL)
1852         {
1853                 (*slp->sl_funcs->scsi_low_targ_init)
1854                         (slp, ti, SCSI_LOW_INFO_ALLOC);
1855         }
1856         scsi_low_calcf_target(ti);
1857         return ti;
1858 }
1859
1860 static void
1861 scsi_low_free_ti(slp)
1862         struct scsi_low_softc *slp;
1863 {
1864         struct targ_info *ti, *tib;
1865         struct lun_info *li, *nli;
1866
1867         for (ti = TAILQ_FIRST(&slp->sl_titab); ti; ti = tib)
1868         {
1869                 for (li = LIST_FIRST(&ti->ti_litab); li != NULL; li = nli)
1870                 {
1871                         if (slp->sl_funcs->scsi_low_lun_init != NULL)
1872                         {
1873                                 (*slp->sl_funcs->scsi_low_lun_init)
1874                                         (slp, ti, li, SCSI_LOW_INFO_DEALLOC);
1875                         }
1876                         nli = LIST_NEXT(li, lun_chain);
1877                         SCSI_LOW_FREE(li);
1878                 }
1879
1880                 if (slp->sl_funcs->scsi_low_targ_init != NULL)
1881                 {
1882                         (*slp->sl_funcs->scsi_low_targ_init)
1883                                 (slp, ti, SCSI_LOW_INFO_DEALLOC);
1884                 }
1885                 tib = TAILQ_NEXT(ti, ti_chain);
1886                 SCSI_LOW_FREE(ti);
1887         }
1888 }
1889
1890 /**************************************************************
1891  * timeout
1892  **************************************************************/
1893 void
1894 scsi_low_bus_idle(slp)
1895         struct scsi_low_softc *slp;
1896 {
1897
1898         slp->sl_retry_sel = 0;
1899         if (slp->sl_Tnexus == NULL)
1900                 scsi_low_start(slp);
1901 }
1902
1903 static void
1904 scsi_low_timeout(arg)
1905         void *arg;
1906 {
1907         struct scsi_low_softc *slp = arg;
1908         int s;
1909
1910         s = SCSI_LOW_SPLSCSI();
1911         (void) scsi_low_timeout_check(slp);
1912         (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
1913                 (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
1914         splx(s);
1915 }
1916
1917 static int
1918 scsi_low_timeout_check(slp)
1919         struct scsi_low_softc *slp;
1920 {
1921         struct targ_info *ti;
1922         struct lun_info *li;
1923         struct slccb *cb = NULL;                /* XXX */
1924
1925         /* selection restart */
1926         if (slp->sl_retry_sel != 0)
1927         {
1928                 slp->sl_retry_sel = 0;
1929                 if (slp->sl_Tnexus != NULL)
1930                         goto step1;
1931
1932                 cb = TAILQ_FIRST(&slp->sl_start);
1933                 if (cb == NULL)
1934                         goto step1;
1935
1936                 if (cb->ccb_selrcnt >= SCSI_LOW_MAX_SELECTION_RETRY)
1937                 {
1938                         cb->ccb_flags |= CCB_NORETRY;
1939                         cb->ccb_error |= SELTIMEOUTIO;
1940                         if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
1941                                 panic("%s: ccb not finished", slp->sl_xname);
1942                 }
1943
1944                 if (slp->sl_Tnexus == NULL)
1945                         scsi_low_start(slp);
1946         }
1947
1948         /* call hardware timeout */
1949 step1:
1950         if (slp->sl_funcs->scsi_low_timeout != NULL)
1951         {
1952                 (*slp->sl_funcs->scsi_low_timeout) (slp);
1953         }
1954         
1955         if (slp->sl_timeout_count ++ < 
1956             SCSI_LOW_TIMEOUT_CHECK_INTERVAL * SCSI_LOW_TIMEOUT_HZ)
1957                 return 0;
1958
1959         slp->sl_timeout_count = 0;
1960         if (slp->sl_nio > 0)
1961         {
1962                 if ((cb = slp->sl_Qnexus) != NULL)
1963                 {
1964                         cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1965                         if (cb->ccb_tc < 0)
1966                                 goto bus_reset;
1967                 }
1968                 else if (slp->sl_disc == 0)
1969                 {
1970                         if ((cb = TAILQ_FIRST(&slp->sl_start)) == NULL)
1971                                 return 0;
1972
1973                         cb->ccb_tc -= SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1974                         if (cb->ccb_tc < 0)
1975                                 goto bus_reset;
1976                 }
1977                 else for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
1978                           ti = TAILQ_NEXT(ti, ti_chain))
1979                 {
1980                         if (ti->ti_disc == 0)
1981                                 continue;
1982
1983                         for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
1984                              li = LIST_NEXT(li, lun_chain))
1985                         {
1986                                 for (cb = TAILQ_FIRST(&li->li_discq); 
1987                                      cb != NULL;
1988                                      cb = TAILQ_NEXT(cb, ccb_chain))
1989                                 {
1990                                         cb->ccb_tc -=
1991                                                 SCSI_LOW_TIMEOUT_CHECK_INTERVAL;
1992                                         if (cb->ccb_tc < 0)
1993                                                 goto bus_reset;
1994                                 }
1995                         }
1996                 }
1997
1998         }
1999         else if ((slp->sl_flags & HW_POWERCTRL) != 0)
2000         {
2001                 if ((slp->sl_flags & (HW_POWDOWN | HW_RESUME)) != 0)
2002                         return 0;
2003
2004                 if (slp->sl_active != 0)
2005                 {
2006                         slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2007                         slp->sl_active = 0;
2008                         return 0;
2009                 }
2010
2011                 slp->sl_powc --;
2012                 if (slp->sl_powc < 0)
2013                 {
2014                         slp->sl_powc = SCSI_LOW_POWDOWN_TC;
2015                         slp->sl_flags |= HW_POWDOWN;
2016                         (*slp->sl_funcs->scsi_low_power)
2017                                         (slp, SCSI_LOW_POWDOWN);
2018                 }
2019         }
2020         return 0;
2021
2022 bus_reset:
2023         cb->ccb_error |= TIMEOUTIO;
2024         printf("%s: slccb (0x%lx) timeout!\n", slp->sl_xname, (u_long) cb);
2025         scsi_low_info(slp, NULL, "scsi bus hangup. try to recover.");
2026         scsi_low_init(slp, SCSI_LOW_RESTART_HARD);
2027         scsi_low_start(slp);
2028         return ERESTART;
2029 }
2030
2031
2032 static int
2033 scsi_low_abort_ccb(slp, cb)
2034         struct scsi_low_softc *slp;
2035         struct slccb *cb;
2036 {
2037         struct targ_info *ti;
2038         struct lun_info *li;
2039         u_int msg;
2040
2041         if (cb == NULL)
2042                 return EINVAL;
2043         if ((cb->ccb_omsgoutflag & 
2044              (SCSI_LOW_MSG_ABORT | SCSI_LOW_MSG_ABORT_QTAG)) != 0)
2045                 return EBUSY;
2046
2047         ti = cb->ti;
2048         li = cb->li;
2049         if (cb->ccb_tag == SCSI_LOW_UNKTAG)
2050                 msg = SCSI_LOW_MSG_ABORT;
2051         else
2052                 msg = SCSI_LOW_MSG_ABORT_QTAG;
2053
2054         cb->ccb_error |= ABORTIO;
2055         cb->ccb_flags |= CCB_NORETRY;
2056         scsi_low_ccb_message_assert(cb, msg);
2057
2058         if (cb == slp->sl_Qnexus)
2059         {
2060                 scsi_low_assert_msg(slp, ti, msg, 1);
2061         }
2062         else if ((cb->ccb_flags & CCB_DISCQ) != 0)
2063         {
2064                 if (scsi_low_revoke_ccb(slp, cb, 0) == NULL)
2065                         panic("%s: revoked ccb done", slp->sl_xname);
2066
2067                 cb->ccb_flags |= CCB_STARTQ;
2068                 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2069
2070                 if (slp->sl_Tnexus == NULL)
2071                         scsi_low_start(slp);
2072         }
2073         else
2074         {
2075                 if (scsi_low_revoke_ccb(slp, cb, 1) != NULL)
2076                         panic("%s: revoked ccb retried", slp->sl_xname);
2077         }
2078         return 0;
2079 }
2080
2081 /**************************************************************
2082  * Generic SCSI INTERFACE
2083  **************************************************************/
2084 int
2085 scsi_low_attach(slp, openings, ntargs, nluns, targsize, lunsize)
2086         struct scsi_low_softc *slp;
2087         int openings, ntargs, nluns, targsize, lunsize;
2088 {
2089         struct targ_info *ti;
2090         struct lun_info *li;
2091         int s, i, nccb, rv;
2092
2093 #ifdef  SCSI_LOW_INTERFACE_XS
2094         slp->sl_osdep_fp = &scsi_low_osdep_funcs_xs;
2095 #endif  /* SCSI_LOW_INTERFACE_XS */
2096 #ifdef  SCSI_LOW_INTERFACE_CAM
2097         slp->sl_osdep_fp = &scsi_low_osdep_funcs_cam;
2098 #endif  /* SCSI_LOW_INTERFACE_CAM */
2099
2100         if (slp->sl_osdep_fp == NULL)
2101                 panic("scsi_low: interface not spcified");
2102
2103         if (ntargs > SCSI_LOW_NTARGETS)
2104         {
2105                 printf("scsi_low: %d targets are too large\n", ntargs);
2106                 printf("change kernel options SCSI_LOW_NTARGETS");
2107                 return EINVAL;
2108         }
2109
2110         if (openings <= 0)
2111                 slp->sl_openings = (SCSI_LOW_NCCB / ntargs);
2112         else
2113                 slp->sl_openings = openings;
2114         slp->sl_ntargs = ntargs;
2115         slp->sl_nluns = nluns;
2116         slp->sl_max_retry = SCSI_LOW_MAX_RETRY;
2117
2118         if (lunsize < sizeof(struct lun_info))
2119                 lunsize = sizeof(struct lun_info);
2120
2121         if (targsize < sizeof(struct targ_info))
2122                 targsize = sizeof(struct targ_info);
2123
2124         slp->sl_targsize = targsize;
2125         for (i = 0; i < ntargs; i ++)
2126         {
2127                 ti = scsi_low_alloc_ti(slp, i);
2128                 ti->ti_lunsize = lunsize;
2129                 li = scsi_low_alloc_li(ti, 0, 1);
2130         }
2131
2132         /* initialize queue */
2133         nccb = openings * ntargs;
2134         if (nccb >= SCSI_LOW_NCCB || nccb <= 0)
2135                 nccb = SCSI_LOW_NCCB;
2136         scsi_low_init_ccbque(nccb);
2137         TAILQ_INIT(&slp->sl_start);
2138
2139         /* call os depend attach */
2140         s = SCSI_LOW_SPLSCSI();
2141         rv = (*slp->sl_osdep_fp->scsi_low_osdep_attach) (slp);
2142         if (rv != 0)
2143         {
2144                 splx(s);
2145                 printf("%s: scsi_low_attach: osdep attach failed\n",
2146                         slp->sl_xname);
2147                 return EINVAL;
2148         }
2149
2150         /* check hardware */
2151         SCSI_LOW_DELAY(1000);   /* wait for 1ms */
2152         if (scsi_low_init(slp, SCSI_LOW_RESTART_HARD) != 0)
2153         {
2154                 splx(s);
2155                 printf("%s: scsi_low_attach: initialization failed\n",
2156                         slp->sl_xname);
2157                 return EINVAL;
2158         }
2159
2160         /* start watch dog */
2161         slp->sl_timeout_count = 0;
2162         (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2163                  (slp, SCSI_LOW_TIMEOUT_CH_IO, SCSI_LOW_TIMEOUT_START);
2164         LIST_INSERT_HEAD(&sl_tab, slp, sl_chain);
2165
2166         /* fake call */
2167         scsi_low_abort_ccb(slp, scsi_low_find_ccb(slp, 0, 0, NULL));
2168
2169 #ifdef  SCSI_LOW_START_UP_CHECK
2170         /* probing devices */
2171         scsi_low_start_up(slp);
2172 #endif  /* SCSI_LOW_START_UP_CHECK */
2173
2174         /* call os depend attach done*/
2175         (*slp->sl_osdep_fp->scsi_low_osdep_world_start) (slp);
2176         splx(s);
2177         return 0;
2178 }
2179
2180 int
2181 scsi_low_dettach(slp)
2182         struct scsi_low_softc *slp;
2183 {
2184         int s, rv;
2185
2186         s = SCSI_LOW_SPLSCSI();
2187         if (scsi_low_is_busy(slp) != 0)
2188         {
2189                 splx(s);
2190                 return EBUSY;
2191         }
2192
2193         scsi_low_deactivate(slp);
2194
2195         rv = (*slp->sl_osdep_fp->scsi_low_osdep_dettach) (slp);
2196         if (rv != 0)
2197         {
2198                 splx(s);
2199                 return EBUSY;
2200         }
2201
2202         scsi_low_free_ti(slp);
2203         LIST_REMOVE(slp, sl_chain);
2204         splx(s);
2205         return 0;
2206 }
2207
2208 /**************************************************************
2209  * Generic enqueue
2210  **************************************************************/
2211 static int
2212 scsi_low_enqueue(slp, ti, li, cb, flags, msg)
2213         struct scsi_low_softc *slp;
2214         struct targ_info *ti;
2215         struct lun_info *li;
2216         struct slccb *cb;
2217         u_int flags, msg;
2218 {       
2219
2220         cb->ti = ti;
2221         cb->li = li;
2222
2223         scsi_low_ccb_message_assert(cb, msg);
2224
2225         cb->ccb_otag = cb->ccb_tag = SCSI_LOW_UNKTAG;
2226         scsi_low_alloc_qtag(cb);
2227
2228         cb->ccb_flags = flags | CCB_STARTQ;
2229         cb->ccb_tc = cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2230         cb->ccb_error |= PENDINGIO;
2231
2232         if ((flags & CCB_URGENT) != 0)
2233         {
2234                 TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2235         }
2236         else
2237         {
2238                 TAILQ_INSERT_TAIL(&slp->sl_start, cb, ccb_chain);
2239         }
2240
2241         slp->sl_nio ++;
2242
2243         if (slp->sl_Tnexus == NULL)
2244                 scsi_low_start(slp);
2245         return 0;
2246 }
2247
2248 static int
2249 scsi_low_message_enqueue(slp, ti, li, flags)
2250         struct scsi_low_softc *slp;
2251         struct targ_info *ti;
2252         struct lun_info *li;
2253         u_int flags;
2254 {
2255         struct slccb *cb;
2256         u_int tmsgflags;
2257
2258         tmsgflags = ti->ti_setup_msg;
2259         ti->ti_setup_msg = 0;
2260
2261         flags |= CCB_NORETRY;
2262         if ((cb = SCSI_LOW_ALLOC_CCB(1)) == NULL)
2263                 return ENOMEM;
2264
2265         cb->osdep = NULL;
2266         cb->bp = NULL;
2267         scsi_low_enqueue(slp, ti, li, cb, flags, tmsgflags);
2268         return 0;
2269 }
2270
2271 /**************************************************************
2272  * Generic Start & Done
2273  **************************************************************/
2274 #define SLSC_MODE_SENSE_SHORT   0x1a
2275 static u_int8_t ss_cmd[6] = {START_STOP, 0, 0, 0, SSS_START, 0}; 
2276 static u_int8_t sms_cmd[6] = {SLSC_MODE_SENSE_SHORT, 0x08, 0x0a, 0, 
2277                               sizeof(struct scsi_low_mode_sense_data), 0}; 
2278 static u_int8_t inq_cmd[6] = {INQUIRY, 0, 0, 0, 
2279                               sizeof(struct scsi_low_inq_data), 0}; 
2280 static u_int8_t unit_ready_cmd[6];
2281 static int scsi_low_setup_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
2282 static int scsi_low_sense_abort_start (struct scsi_low_softc *, struct targ_info *, struct lun_info *, struct slccb *);
2283 static int scsi_low_resume (struct scsi_low_softc *);
2284
2285 static void
2286 scsi_low_unit_ready_cmd(cb)
2287         struct slccb *cb;
2288 {
2289
2290         cb->ccb_scp.scp_cmd = unit_ready_cmd;
2291         cb->ccb_scp.scp_cmdlen = sizeof(unit_ready_cmd);
2292         cb->ccb_scp.scp_datalen = 0;
2293         cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2294         cb->ccb_tcmax = 15;
2295 }
2296
2297 static int
2298 scsi_low_sense_abort_start(slp, ti, li, cb)
2299         struct scsi_low_softc *slp;
2300         struct targ_info *ti;
2301         struct lun_info *li;
2302         struct slccb *cb;
2303 {
2304
2305         cb->ccb_scp.scp_cmdlen = 6;
2306         SCSI_LOW_BZERO(cb->ccb_scsi_cmd, cb->ccb_scp.scp_cmdlen);
2307         cb->ccb_scsi_cmd[0] = REQUEST_SENSE;
2308         cb->ccb_scsi_cmd[4] = sizeof(cb->ccb_sense);
2309         cb->ccb_scp.scp_cmd = cb->ccb_scsi_cmd;
2310         cb->ccb_scp.scp_data = (u_int8_t *) &cb->ccb_sense;
2311         cb->ccb_scp.scp_datalen = sizeof(cb->ccb_sense);
2312         cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2313         cb->ccb_tcmax = 15;
2314         scsi_low_ccb_message_clear(cb);
2315         if ((cb->ccb_flags & CCB_CLEARQ) != 0)
2316         {
2317                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
2318         }
2319         else
2320         {
2321                 SCSI_LOW_BZERO(&cb->ccb_sense, sizeof(cb->ccb_sense));
2322 #ifdef  SCSI_LOW_NEGOTIATE_BEFORE_SENSE
2323                 scsi_low_assert_msg(slp, ti, ti->ti_setup_msg_done, 0);
2324 #endif  /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
2325         }
2326
2327         return SCSI_LOW_START_NO_QTAG;
2328 }
2329
2330 static int
2331 scsi_low_setup_start(slp, ti, li, cb)
2332         struct scsi_low_softc *slp;
2333         struct targ_info *ti;
2334         struct lun_info *li;
2335         struct slccb *cb;
2336 {
2337
2338         switch(li->li_state)
2339         {
2340         case SCSI_LOW_LUN_SLEEP:
2341                 scsi_low_unit_ready_cmd(cb);
2342                 break;
2343
2344         case SCSI_LOW_LUN_START:
2345                 cb->ccb_scp.scp_cmd = ss_cmd;
2346                 cb->ccb_scp.scp_cmdlen = sizeof(ss_cmd);
2347                 cb->ccb_scp.scp_datalen = 0;
2348                 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2349                 cb->ccb_tcmax = 30;
2350                 break;
2351
2352         case SCSI_LOW_LUN_INQ:
2353                 cb->ccb_scp.scp_cmd = inq_cmd;
2354                 cb->ccb_scp.scp_cmdlen = sizeof(inq_cmd);
2355                 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_inq;
2356                 cb->ccb_scp.scp_datalen = sizeof(li->li_inq);
2357                 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2358                 cb->ccb_tcmax = 15;
2359                 break;
2360
2361         case SCSI_LOW_LUN_MODEQ:
2362                 cb->ccb_scp.scp_cmd = sms_cmd;
2363                 cb->ccb_scp.scp_cmdlen = sizeof(sms_cmd);
2364                 cb->ccb_scp.scp_data = (u_int8_t *)&li->li_sms;
2365                 cb->ccb_scp.scp_datalen = sizeof(li->li_sms);
2366                 cb->ccb_scp.scp_direction = SCSI_LOW_READ;
2367                 cb->ccb_tcmax = 15;
2368                 return SCSI_LOW_START_QTAG;
2369
2370         default:
2371                 panic("%s: no setup phase", slp->sl_xname);
2372         }
2373
2374         return SCSI_LOW_START_NO_QTAG;
2375 }
2376
2377 static int
2378 scsi_low_resume(slp)
2379         struct scsi_low_softc *slp;
2380 {
2381
2382         if (slp->sl_flags & HW_RESUME)
2383                 return EJUSTRETURN;
2384         slp->sl_flags &= ~HW_POWDOWN;
2385         if (slp->sl_funcs->scsi_low_power != NULL)
2386         {
2387                 slp->sl_flags |= HW_RESUME;
2388                 slp->sl_rstep = 0;
2389                 (*slp->sl_funcs->scsi_low_power) (slp, SCSI_LOW_ENGAGE);
2390                 (*slp->sl_osdep_fp->scsi_low_osdep_timeout)
2391                                         (slp, SCSI_LOW_TIMEOUT_CH_ENGAGE,
2392                                          SCSI_LOW_TIMEOUT_START);
2393                 return EJUSTRETURN;
2394         }
2395         return 0;
2396 }
2397
2398 static void
2399 scsi_low_start(slp)
2400         struct scsi_low_softc *slp;
2401 {
2402         struct targ_info *ti;
2403         struct lun_info *li;
2404         struct slccb *cb;
2405         int rv;
2406
2407         /* check hardware exists or under initializations ? */
2408         if ((slp->sl_flags & (HW_INACTIVE | HW_INITIALIZING)) != 0)
2409                 return;
2410
2411         /* check hardware power up ? */
2412         if ((slp->sl_flags & HW_POWERCTRL) != 0)
2413         {
2414                 slp->sl_active ++;
2415                 if (slp->sl_flags & (HW_POWDOWN | HW_RESUME))
2416                 {
2417                         if (scsi_low_resume(slp) == EJUSTRETURN)
2418                                 return;
2419                 }
2420         }
2421
2422         /* setup nexus */
2423 #ifdef  SCSI_LOW_DIAGNOSTIC
2424         if (slp->sl_Tnexus || slp->sl_Lnexus || slp->sl_Qnexus)
2425         {
2426                 scsi_low_info(slp, NULL, "NEXUS INCOSISTENT");
2427                 panic("%s: inconsistent", slp->sl_xname);
2428         }
2429 #endif  /* SCSI_LOW_DIAGNOSTIC */
2430
2431         for (cb = TAILQ_FIRST(&slp->sl_start); cb != NULL;
2432              cb = TAILQ_NEXT(cb, ccb_chain))
2433         {
2434                 li = cb->li;
2435
2436                 if (li->li_disc == 0)
2437                 {
2438                         goto scsi_low_cmd_start;
2439                 }
2440                 else if (li->li_nqio > 0)
2441                 {
2442                         if (li->li_nqio < li->li_maxnqio ||
2443                             (cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2444                                 goto scsi_low_cmd_start;
2445                 }
2446         }
2447         return;
2448
2449 scsi_low_cmd_start:
2450         cb->ccb_flags &= ~CCB_STARTQ;
2451         TAILQ_REMOVE(&slp->sl_start, cb, ccb_chain);
2452         ti = cb->ti;
2453
2454         /* clear all error flag bits (for restart) */
2455         cb->ccb_error = 0;
2456         cb->ccb_datalen = -1;
2457         cb->ccb_scp.scp_status = ST_UNKNOWN;
2458
2459         /* setup nexus pointer */
2460         slp->sl_Qnexus = cb;
2461         slp->sl_Lnexus = li;
2462         slp->sl_Tnexus = ti;
2463
2464         /* initialize msgsys */
2465         scsi_low_init_msgsys(slp, ti);
2466
2467         /* exec cmd */
2468         if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2469         {
2470                 /* CA state or forced abort */
2471                 rv = scsi_low_sense_abort_start(slp, ti, li, cb);
2472         }
2473         else if (li->li_state >= SCSI_LOW_LUN_OK)
2474         {
2475                 cb->ccb_flags &= ~CCB_INTERNAL;
2476                 rv = (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, cb);
2477                 if (cb->ccb_msgoutflag != 0)
2478                 {
2479                         scsi_low_ccb_message_exec(slp, cb);
2480                 }
2481         }
2482         else
2483         {
2484                 cb->ccb_flags |= CCB_INTERNAL;
2485                 rv = scsi_low_setup_start(slp, ti, li, cb);
2486         }
2487
2488         /* allocate qtag */
2489 #define SCSI_LOW_QTAG_OK (SCSI_LOW_QTAG | SCSI_LOW_DISC)
2490
2491         if (rv == SCSI_LOW_START_QTAG &&
2492             (li->li_flags & SCSI_LOW_QTAG_OK) == SCSI_LOW_QTAG_OK &&
2493             li->li_maxnqio > 0)
2494         {
2495                 u_int qmsg;
2496
2497                 scsi_low_activate_qtag(cb);
2498                 if ((scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2499                      SCSI_LOW_CMD_ORDERED_QTAG) != 0)
2500                         qmsg = SCSI_LOW_MSG_ORDERED_QTAG;
2501                 else if ((cb->ccb_flags & CCB_URGENT) != 0)
2502                         qmsg = SCSI_LOW_MSG_HEAD_QTAG;
2503                 else
2504                         qmsg = SCSI_LOW_MSG_SIMPLE_QTAG;
2505                 scsi_low_assert_msg(slp, ti, qmsg, 0);
2506         }
2507
2508         /* timeout */
2509         if (cb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
2510                 cb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
2511         cb->ccb_tc = cb->ccb_tcmax;
2512
2513         /* setup saved scsi data pointer */
2514         cb->ccb_sscp = cb->ccb_scp;
2515
2516         /* setup current scsi pointer */ 
2517         slp->sl_scp = cb->ccb_sscp;
2518         slp->sl_error = cb->ccb_error;
2519
2520         /* assert always an identify msg */
2521         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_IDENTIFY, 0);
2522
2523         /* debug section */
2524 #ifdef  SCSI_LOW_DIAGNOSTIC
2525         scsi_low_msg_log_init(&ti->ti_log_msgin);
2526         scsi_low_msg_log_init(&ti->ti_log_msgout);
2527 #endif  /* SCSI_LOW_DIAGNOSTIC */
2528
2529         /* selection start */
2530         slp->sl_selid = cb;
2531         rv = ((*slp->sl_funcs->scsi_low_start_bus) (slp, cb));
2532         if (rv == SCSI_LOW_START_OK)
2533         {
2534 #ifdef  SCSI_LOW_STATICS
2535                 scsi_low_statics.nexus_win ++;
2536 #endif  /* SCSI_LOW_STATICS */
2537                 return;
2538         }
2539
2540         scsi_low_arbit_fail(slp, cb);
2541 #ifdef  SCSI_LOW_STATICS
2542         scsi_low_statics.nexus_fail ++;
2543 #endif  /* SCSI_LOW_STATICS */
2544 }
2545
2546 void
2547 scsi_low_arbit_fail(slp, cb)
2548         struct scsi_low_softc *slp;
2549         struct slccb *cb;
2550 {
2551         struct targ_info *ti = cb->ti;
2552
2553         scsi_low_deactivate_qtag(cb);
2554         scsi_low_ccb_message_retry(cb);
2555         cb->ccb_flags |= CCB_STARTQ;
2556         TAILQ_INSERT_HEAD(&slp->sl_start, cb, ccb_chain);
2557
2558         scsi_low_bus_release(slp, ti);
2559
2560         cb->ccb_selrcnt ++;
2561         if (slp->sl_disc == 0)
2562         {
2563 #ifdef  SCSI_LOW_DIAGNOSTIC
2564                 printf("%s: try selection again\n", slp->sl_xname);
2565 #endif  /* SCSI_LOW_DIAGNOSTIC */
2566                 slp->sl_retry_sel = 1;
2567         }
2568 }
2569
2570 static void
2571 scsi_low_bus_release(slp, ti)
2572         struct scsi_low_softc *slp;
2573         struct targ_info *ti;
2574 {
2575
2576         if (ti->ti_disc > 0)
2577         {
2578                 SCSI_LOW_SETUP_PHASE(ti, PH_DISC);
2579         }
2580         else
2581         {
2582                 SCSI_LOW_SETUP_PHASE(ti, PH_NULL);
2583         }
2584
2585         /* clear all nexus pointer */
2586         slp->sl_Qnexus = NULL;
2587         slp->sl_Lnexus = NULL;
2588         slp->sl_Tnexus = NULL;
2589
2590         /* clear selection assert */
2591         slp->sl_selid = NULL;
2592
2593         /* clear nexus data */
2594         slp->sl_scp.scp_direction = SCSI_LOW_RWUNK;
2595
2596         /* clear phase change counter */
2597         slp->sl_ph_count = 0;
2598 }
2599
2600 static int
2601 scsi_low_setup_done(slp, cb)
2602         struct scsi_low_softc *slp;
2603         struct slccb *cb;
2604 {
2605         struct targ_info *ti;
2606         struct lun_info *li;
2607
2608         ti = cb->ti;
2609         li = cb->li;
2610
2611         if (cb->ccb_rcnt >= slp->sl_max_retry)
2612         {
2613                 cb->ccb_error |= ABORTIO;
2614                 return SCSI_LOW_DONE_COMPLETE;
2615         }
2616
2617         /* XXX: special huck for selection timeout */
2618         if (li->li_state == SCSI_LOW_LUN_SLEEP &&
2619             (cb->ccb_error & SELTIMEOUTIO) != 0)
2620         {
2621                 cb->ccb_error |= ABORTIO;
2622                 return SCSI_LOW_DONE_COMPLETE;
2623         }
2624
2625         switch(li->li_state)
2626         {
2627         case SCSI_LOW_LUN_INQ:
2628                 if (cb->ccb_error != 0)
2629                 {
2630                         li->li_diskflags &= 
2631                                 ~(SCSI_LOW_DISK_LINK | SCSI_LOW_DISK_QTAG);
2632                         if (li->li_lun > 0)
2633                                 goto resume;
2634                         ti->ti_diskflags &=
2635                                 ~(SCSI_LOW_DISK_SYNC | SCSI_LOW_DISK_WIDE);
2636                 }
2637                 else if ((li->li_inq.sd_version & 7) >= 2 ||
2638                          (li->li_inq.sd_len >= 4))
2639                 {
2640                         if ((li->li_inq.sd_support & 0x2) == 0)
2641                                 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2642                         if ((li->li_inq.sd_support & 0x8) == 0)
2643                                 li->li_diskflags &= ~SCSI_LOW_DISK_LINK;
2644                         if (li->li_lun > 0)
2645                                 goto resume;
2646                         if ((li->li_inq.sd_support & 0x10) == 0)
2647                                 ti->ti_diskflags &= ~SCSI_LOW_DISK_SYNC;
2648                         if ((li->li_inq.sd_support & 0x20) == 0)
2649                                 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_16;
2650                         if ((li->li_inq.sd_support & 0x40) == 0)
2651                                 ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE_32;
2652                 }
2653                 else
2654                 {
2655                         li->li_diskflags &= 
2656                                 ~(SCSI_LOW_DISK_QTAG | SCSI_LOW_DISK_LINK);
2657                         if (li->li_lun > 0)
2658                                 goto resume;
2659                         ti->ti_diskflags &= ~SCSI_LOW_DISK_WIDE;
2660                 }
2661                 ti->ti_flags_valid |= SCSI_LOW_TARG_FLAGS_DISK_VALID;
2662 resume:
2663                 scsi_low_calcf_target(ti);
2664                 scsi_low_calcf_lun(li);
2665                 break;
2666
2667         case SCSI_LOW_LUN_MODEQ:
2668                 if (cb->ccb_error != 0)
2669                 {
2670                         if (cb->ccb_error & SENSEIO)
2671                         {
2672 #ifdef  SCSI_LOW_DEBUG
2673                                 if (scsi_low_debug & SCSI_LOW_DEBUG_SENSE)
2674                                 {
2675                                         printf("SENSE: [%x][%x][%x][%x][%x]\n",
2676                                         (u_int) cb->ccb_sense.error_code,
2677                                         (u_int) cb->ccb_sense.segment,
2678                                         (u_int) cb->ccb_sense.flags,
2679                                         (u_int) cb->ccb_sense.add_sense_code,
2680                                         (u_int) cb->ccb_sense.add_sense_code_qual);
2681                                 }
2682 #endif  /* SCSI_LOW_DEBUG */
2683                         }
2684                         else
2685                         {
2686                                 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2687                         }
2688                 }
2689                 else if ((li->li_sms.sms_cmp.cmp_page & 0x3f) == 0x0a)
2690                 {       
2691                         if (li->li_sms.sms_cmp.cmp_qc & 0x02)
2692                                 li->li_qflags |= SCSI_LOW_QFLAG_CA_QCLEAR;
2693                         else
2694                                 li->li_qflags &= ~SCSI_LOW_QFLAG_CA_QCLEAR;
2695                         if ((li->li_sms.sms_cmp.cmp_qc & 0x01) != 0)
2696                                 li->li_diskflags &= ~SCSI_LOW_DISK_QTAG;
2697                 }
2698                 li->li_flags_valid |= SCSI_LOW_LUN_FLAGS_DISK_VALID;
2699                 scsi_low_calcf_lun(li);
2700                 break;
2701
2702         default:
2703                 break;
2704         }
2705
2706         li->li_state ++;
2707         if (li->li_state == SCSI_LOW_LUN_OK)
2708         {
2709                 scsi_low_calcf_target(ti);
2710                 scsi_low_calcf_lun(li);
2711                 if (li->li_flags_valid == SCSI_LOW_LUN_FLAGS_ALL_VALID &&
2712                     (slp->sl_show_result & SHOW_CALCF_RES) != 0)
2713                 {
2714                         scsi_low_calcf_show(li);
2715                 }       
2716         }
2717
2718         cb->ccb_rcnt --;
2719         return SCSI_LOW_DONE_RETRY;
2720 }
2721
2722 static int
2723 scsi_low_done(slp, cb)
2724         struct scsi_low_softc *slp;
2725         struct slccb *cb;
2726 {
2727         int rv;
2728
2729         if (cb->ccb_error == 0)
2730         {
2731                 if ((cb->ccb_flags & (CCB_SENSE | CCB_CLEARQ)) != 0)
2732                 {
2733 #ifdef  SCSI_LOW_QCLEAR_AFTER_CA
2734                         /* XXX:
2735                          * SCSI-2 draft suggests 
2736                          * page 0x0a QErr bit determins if
2737                          * the target aborts or continues
2738                          * the queueing io's after CA state resolved.
2739                          * However many targets seem not to support
2740                          * the page 0x0a. Thus we should manually clear the
2741                          * queuing io's after CA state.
2742                          */
2743                         if ((cb->ccb_flags & CCB_CLEARQ) == 0)
2744                         {
2745                                 cb->ccb_rcnt --;
2746                                 cb->ccb_flags |= CCB_CLEARQ;
2747                                 goto retry;
2748                         }
2749 #endif  /* SCSI_LOW_QCLEAR_AFTER_CA */
2750
2751                         if ((cb->ccb_flags & CCB_SENSE) != 0)
2752                                 cb->ccb_error |= (SENSEIO | ABORTIO);
2753                         cb->ccb_flags &= ~(CCB_SENSE | CCB_CLEARQ);
2754                 }
2755                 else switch (cb->ccb_sscp.scp_status)
2756                 {
2757                 case ST_GOOD:
2758                 case ST_MET:
2759                 case ST_INTERGOOD:
2760                 case ST_INTERMET:
2761                         if (cb->ccb_datalen == 0 ||
2762                             cb->ccb_scp.scp_datalen == 0)
2763                                 break;
2764
2765                         if (cb->ccb_scp.scp_cmdlen > 0 &&
2766                             (scsi_low_cmd_flags[cb->ccb_scp.scp_cmd[0]] &
2767                              SCSI_LOW_CMD_RESIDUAL_CHK) == 0)
2768                                 break;
2769
2770                         cb->ccb_error |= PDMAERR;
2771                         break;
2772
2773                 case ST_BUSY:
2774                 case ST_QUEFULL:
2775                         cb->ccb_error |= (BUSYERR | STATERR);
2776                         break;
2777
2778                 case ST_CONFLICT:
2779                         cb->ccb_error |= (STATERR | ABORTIO);
2780                         break;
2781
2782                 case ST_CHKCOND:
2783                 case ST_CMDTERM:
2784                         if (cb->ccb_flags & (CCB_AUTOSENSE | CCB_INTERNAL))
2785                         {
2786                                 cb->ccb_rcnt --;
2787                                 cb->ccb_flags |= CCB_SENSE;
2788                                 goto retry;
2789                         }
2790                         cb->ccb_error |= (UACAERR | STATERR | ABORTIO);
2791                         break;
2792
2793                 case ST_UNKNOWN:
2794                 default:
2795                         cb->ccb_error |= FATALIO;
2796                         break;
2797                 }
2798         }
2799         else
2800         {
2801                 if (cb->ccb_flags & CCB_SENSE)
2802                 {
2803                         cb->ccb_error |= (SENSEERR | ABORTIO);
2804                 }
2805                 cb->ccb_flags &= ~(CCB_CLEARQ | CCB_SENSE);
2806         }
2807
2808         /* internal ccb */
2809         if ((cb->ccb_flags & CCB_INTERNAL) != 0)
2810         {
2811                 if (scsi_low_setup_done(slp, cb) == SCSI_LOW_DONE_RETRY)
2812                         goto retry;
2813         }
2814
2815         /* check a ccb msgout flag */
2816         if (cb->ccb_omsgoutflag != 0)
2817         {
2818 #define SCSI_LOW_MSG_ABORT_OK   (SCSI_LOW_MSG_ABORT | \
2819                                  SCSI_LOW_MSG_ABORT_QTAG | \
2820                                  SCSI_LOW_MSG_CLEAR_QTAG | \
2821                                  SCSI_LOW_MSG_TERMIO)
2822
2823                 if ((cb->ccb_omsgoutflag & SCSI_LOW_MSG_ABORT_OK) != 0)
2824                 {
2825                         cb->ccb_error |= ABORTIO;
2826                 }
2827         }
2828
2829         /* call OS depend done */
2830         if (cb->osdep != NULL)
2831         {
2832                 rv = (*slp->sl_osdep_fp->scsi_low_osdep_done) (slp, cb);
2833                 if (rv == EJUSTRETURN)
2834                         goto retry;
2835         }
2836         else if (cb->ccb_error != 0)
2837         {
2838                 if (cb->ccb_rcnt >= slp->sl_max_retry)
2839                         cb->ccb_error |= ABORTIO;
2840
2841                 if ((cb->ccb_flags & CCB_NORETRY) == 0 &&
2842                     (cb->ccb_error & ABORTIO) == 0)
2843                         goto retry;
2844         }
2845
2846         /* free our target */
2847 #ifdef  SCSI_LOW_DEBUG
2848         if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2849         {
2850                 printf(">> SCSI_LOW_DONE_COMPLETE ===============\n");
2851                 scsi_low_print(slp, NULL);
2852         }
2853 #endif  /* SCSI_LOW_DEBUG */
2854
2855         scsi_low_deactivate_qtag(cb);
2856         scsi_low_dealloc_qtag(cb);
2857         scsi_low_free_ccb(cb);
2858         slp->sl_nio --;
2859         return SCSI_LOW_DONE_COMPLETE;
2860
2861 retry:
2862 #ifdef  SCSI_LOW_DEBUG
2863         if (SCSI_LOW_DEBUG_GO(SCSI_LOW_DEBUG_DONE, cb->ti->ti_id) != 0)
2864         {
2865                 printf("** SCSI_LOW_DONE_RETRY ===============\n");
2866                 scsi_low_print(slp, NULL);
2867         }
2868 #endif  /* SCSI_LOW_DEBUG */
2869                 
2870         cb->ccb_rcnt ++;
2871         scsi_low_deactivate_qtag(cb);
2872         scsi_low_ccb_message_retry(cb);
2873         return SCSI_LOW_DONE_RETRY;
2874 }
2875
2876 /**************************************************************
2877  * Reset
2878  **************************************************************/
2879 static void
2880 scsi_low_reset_nexus_target(slp, ti, fdone)
2881         struct scsi_low_softc *slp;
2882         struct targ_info *ti;
2883         int fdone;
2884 {
2885         struct lun_info *li;
2886
2887         for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2888              li = LIST_NEXT(li, lun_chain))
2889         {
2890                 scsi_low_reset_nexus_lun(slp, li, fdone);
2891                 li->li_state = SCSI_LOW_LUN_SLEEP;
2892                 li->li_maxnqio = 0;
2893         }
2894
2895         ti->ti_disc = 0;
2896         ti->ti_setup_msg = 0;
2897         ti->ti_setup_msg_done = 0;
2898
2899         ti->ti_osynch.offset = ti->ti_osynch.period = 0;
2900         ti->ti_owidth = SCSI_LOW_BUS_WIDTH_8;
2901
2902         ti->ti_diskflags = SCSI_LOW_DISK_TFLAGS;
2903         ti->ti_flags_valid &= ~SCSI_LOW_TARG_FLAGS_DISK_VALID;
2904
2905         if (slp->sl_funcs->scsi_low_targ_init != NULL)
2906         {
2907                 ((*slp->sl_funcs->scsi_low_targ_init)
2908                         (slp, ti, SCSI_LOW_INFO_REVOKE));
2909         }
2910         scsi_low_calcf_target(ti);
2911
2912         for (li = LIST_FIRST(&ti->ti_litab); li != NULL;
2913              li = LIST_NEXT(li, lun_chain))
2914         {
2915                 li->li_flags = 0;
2916
2917                 li->li_diskflags = SCSI_LOW_DISK_LFLAGS;
2918                 li->li_flags_valid &= ~SCSI_LOW_LUN_FLAGS_DISK_VALID;
2919
2920                 if (slp->sl_funcs->scsi_low_lun_init != NULL)
2921                 {
2922                         ((*slp->sl_funcs->scsi_low_lun_init)
2923                                 (slp, ti, li, SCSI_LOW_INFO_REVOKE));
2924                 }
2925                 scsi_low_calcf_lun(li);
2926         }
2927 }
2928
2929 static void
2930 scsi_low_reset_nexus(slp, fdone)
2931         struct scsi_low_softc *slp;
2932         int fdone;
2933 {
2934         struct targ_info *ti;
2935         struct slccb *cb, *topcb;
2936
2937         if ((cb = slp->sl_Qnexus) != NULL)
2938         {
2939                 topcb = scsi_low_revoke_ccb(slp, cb, fdone);
2940         }
2941         else
2942         {
2943                 topcb = NULL;
2944         }
2945
2946         for (ti = TAILQ_FIRST(&slp->sl_titab); ti != NULL;
2947              ti = TAILQ_NEXT(ti, ti_chain))
2948         {
2949                 scsi_low_reset_nexus_target(slp, ti, fdone);
2950                 scsi_low_bus_release(slp, ti);
2951                 scsi_low_init_msgsys(slp, ti);
2952         }
2953
2954         if (topcb != NULL)
2955         {
2956                 topcb->ccb_flags |= CCB_STARTQ;
2957                 TAILQ_INSERT_HEAD(&slp->sl_start, topcb, ccb_chain);
2958         }
2959
2960         slp->sl_disc = 0;
2961         slp->sl_retry_sel = 0;
2962         slp->sl_flags &= ~HW_PDMASTART;
2963 }
2964
2965 /* misc */
2966 static int tw_pos;
2967 static char tw_chars[] = "|/-\\";
2968 #define TWIDDLEWAIT             10000
2969
2970 static void
2971 scsi_low_twiddle_wait(void)
2972 {
2973
2974         cnputc('\b');
2975         cnputc(tw_chars[tw_pos++]);
2976         tw_pos %= (sizeof(tw_chars) - 1);
2977         SCSI_LOW_DELAY(TWIDDLEWAIT);
2978 }
2979
2980 void
2981 scsi_low_bus_reset(slp)
2982         struct scsi_low_softc *slp;
2983 {
2984         int i;
2985
2986         (*slp->sl_funcs->scsi_low_bus_reset) (slp);
2987
2988         printf("%s: try to reset scsi bus  ", slp->sl_xname);
2989         for (i = 0; i <= SCSI2_RESET_DELAY / TWIDDLEWAIT ; i++)
2990                 scsi_low_twiddle_wait();
2991         cnputc('\b');
2992         printf("\n");
2993 }
2994
2995 int
2996 scsi_low_restart(slp, flags, s)
2997         struct scsi_low_softc *slp;
2998         int flags;
2999         u_char *s;
3000 {
3001         int error;
3002
3003         if (s != NULL)
3004                 printf("%s: scsi bus restart. reason: %s\n", slp->sl_xname, s);
3005
3006         if ((error = scsi_low_init(slp, flags)) != 0)
3007                 return error;
3008
3009         scsi_low_start(slp);
3010         return 0;
3011 }
3012
3013 /**************************************************************
3014  * disconnect and reselect
3015  **************************************************************/
3016 #define MSGCMD_LUN(msg) (msg & 0x07)
3017
3018 static struct slccb *
3019 scsi_low_establish_ccb(ti, li, tag)
3020         struct targ_info *ti;
3021         struct lun_info *li;
3022         scsi_low_tag_t tag;
3023 {
3024         struct scsi_low_softc *slp = ti->ti_sc;
3025         struct slccb *cb;
3026
3027         if (li == NULL)
3028                 return NULL;
3029
3030         cb = TAILQ_FIRST(&li->li_discq);
3031         for ( ; cb != NULL; cb = TAILQ_NEXT(cb, ccb_chain))
3032                 if (cb->ccb_tag == tag)
3033                         goto found;
3034         return cb;
3035
3036         /* 
3037          * establish our ccb nexus
3038          */
3039 found:
3040 #ifdef  SCSI_LOW_DEBUG
3041         if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id) != 0)
3042         {
3043                 printf("%s: nexus(0x%lx) abort check start\n",
3044                         slp->sl_xname, (u_long) cb);
3045                 cb->ccb_flags |= (CCB_NORETRY | CCB_SILENT);
3046                 scsi_low_revoke_ccb(slp, cb, 1);
3047                 return NULL;
3048         }
3049
3050         if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id) != 0)
3051         {
3052                 if (cb->ccb_omsgoutflag == 0)
3053                         scsi_low_ccb_message_assert(cb, SCSI_LOW_MSG_NOOP);
3054         }
3055 #endif  /* SCSI_LOW_DEBUG */
3056
3057         TAILQ_REMOVE(&li->li_discq, cb, ccb_chain);
3058         cb->ccb_flags &= ~CCB_DISCQ;
3059         slp->sl_Qnexus = cb;
3060
3061         slp->sl_scp = cb->ccb_sscp;
3062         slp->sl_error |= cb->ccb_error;
3063
3064         slp->sl_disc --;
3065         ti->ti_disc --;
3066         li->li_disc --;
3067
3068         /* inform "ccb nexus established" to the host driver */
3069         (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3070
3071         /* check msg */
3072         if (cb->ccb_msgoutflag != 0)
3073         {
3074                 scsi_low_ccb_message_exec(slp, cb);
3075         }
3076
3077         return cb;
3078 }
3079
3080 struct targ_info *
3081 scsi_low_reselected(slp, targ)
3082         struct scsi_low_softc *slp;
3083         u_int targ;
3084 {
3085         struct targ_info *ti;
3086         struct slccb *cb;
3087         u_char *s;
3088
3089         /* 
3090          * Check select vs reselected collision.
3091          */
3092
3093         if ((cb = slp->sl_selid) != NULL)
3094         {
3095                 scsi_low_arbit_fail(slp, cb);
3096 #ifdef  SCSI_LOW_STATICS
3097                 scsi_low_statics.nexus_conflict ++;
3098 #endif  /* SCSI_LOW_STATICS */
3099         }
3100
3101         /* 
3102          * Check if no current active nexus.
3103          */
3104         if (slp->sl_Tnexus != NULL)
3105         {
3106                 s = "host busy";
3107                 goto world_restart;
3108         }
3109
3110         /* 
3111          * Check a valid target id asserted ?
3112          */
3113         if (targ >= slp->sl_ntargs || targ == slp->sl_hostid)
3114         {
3115                 s = "scsi id illegal";
3116                 goto world_restart;
3117         }
3118
3119         /* 
3120          * Check the target scsi status.
3121          */
3122         ti = slp->sl_ti[targ];
3123         if (ti->ti_phase != PH_DISC && ti->ti_phase != PH_NULL)
3124         {
3125                 s = "phase mismatch";
3126                 goto world_restart;
3127         }
3128
3129         /* 
3130          * Setup init msgsys
3131          */
3132         slp->sl_error = 0;
3133         scsi_low_init_msgsys(slp, ti);
3134
3135         /* 
3136          * Establish our target nexus
3137          */
3138         SCSI_LOW_SETUP_PHASE(ti, PH_RESEL);
3139         slp->sl_Tnexus = ti;
3140 #ifdef  SCSI_LOW_STATICS
3141         scsi_low_statics.nexus_reselected ++;
3142 #endif  /* SCSI_LOW_STATICS */
3143         return ti;
3144
3145 world_restart:
3146         printf("%s: reselect(%x:unknown) %s\n", slp->sl_xname, targ, s);
3147         scsi_low_restart(slp, SCSI_LOW_RESTART_HARD, 
3148                          "reselect: scsi world confused");
3149         return NULL;
3150 }
3151
3152 /**************************************************************
3153  * cmd out pointer setup
3154  **************************************************************/
3155 int
3156 scsi_low_cmd(slp, ti)
3157         struct scsi_low_softc *slp;
3158         struct targ_info *ti;
3159 {
3160         struct slccb *cb = slp->sl_Qnexus;
3161         
3162         slp->sl_ph_count ++;
3163         if (cb == NULL)
3164         {
3165                 /*
3166                  * no ccb, abort!
3167                  */
3168                 slp->sl_scp.scp_cmd = (u_int8_t *) &unit_ready_cmd;
3169                 slp->sl_scp.scp_cmdlen = sizeof(unit_ready_cmd);
3170                 slp->sl_scp.scp_datalen = 0;
3171                 slp->sl_scp.scp_direction = SCSI_LOW_READ;
3172                 slp->sl_error |= FATALIO;
3173                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3174                 SCSI_LOW_INFO(slp, ti, "CMDOUT: ccb nexus not found");
3175                 return EINVAL;
3176         }
3177         else 
3178         {
3179 #ifdef  SCSI_LOW_DEBUG
3180                 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_CMDLNK_CHECK, ti->ti_id))
3181                 {
3182                         scsi_low_test_cmdlnk(slp, cb);
3183                 }
3184 #endif  /* SCSI_LOW_DEBUG */
3185         }
3186         return 0;
3187 }
3188
3189 /**************************************************************
3190  * data out pointer setup
3191  **************************************************************/
3192 int
3193 scsi_low_data(slp, ti, bp, direction)
3194         struct scsi_low_softc *slp;
3195         struct targ_info *ti;
3196         struct buf **bp;
3197         int direction;
3198 {
3199         struct slccb *cb = slp->sl_Qnexus;
3200
3201         if (cb != NULL && direction == cb->ccb_sscp.scp_direction)
3202         {
3203                 *bp = cb->bp;
3204                 return 0;
3205         }
3206
3207         slp->sl_error |= (FATALIO | PDMAERR);
3208         slp->sl_scp.scp_datalen = 0;
3209         slp->sl_scp.scp_direction = direction;
3210         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3211         if (ti->ti_ophase != ti->ti_phase)
3212         {
3213                 char *s;
3214
3215                 if (cb == NULL)
3216                         s = "DATA PHASE: ccb nexus not found";
3217                 else
3218                         s = "DATA PHASE: xfer direction mismatch";
3219                 SCSI_LOW_INFO(slp, ti, s);
3220         }
3221
3222         *bp = NULL;
3223         return EINVAL;
3224 }
3225
3226 /**************************************************************
3227  * MSG_SYS 
3228  **************************************************************/
3229 #define MSGINPTR_CLR(ti) {(ti)->ti_msginptr = 0; (ti)->ti_msginlen = 0;}
3230 #define MSGIN_PERIOD(ti) ((ti)->ti_msgin[3])
3231 #define MSGIN_OFFSET(ti) ((ti)->ti_msgin[4])
3232 #define MSGIN_WIDTHP(ti) ((ti)->ti_msgin[3])
3233 #define MSGIN_DATA_LAST 0x30
3234
3235 static int scsi_low_errfunc_synch (struct scsi_low_softc *, u_int);
3236 static int scsi_low_errfunc_wide (struct scsi_low_softc *, u_int);
3237 static int scsi_low_errfunc_identify (struct scsi_low_softc *, u_int);
3238 static int scsi_low_errfunc_qtag (struct scsi_low_softc *, u_int);
3239
3240 static int scsi_low_msgfunc_synch (struct scsi_low_softc *);
3241 static int scsi_low_msgfunc_wide (struct scsi_low_softc *);
3242 static int scsi_low_msgfunc_identify (struct scsi_low_softc *);
3243 static int scsi_low_msgfunc_abort (struct scsi_low_softc *);
3244 static int scsi_low_msgfunc_qabort (struct scsi_low_softc *);
3245 static int scsi_low_msgfunc_qtag (struct scsi_low_softc *);
3246 static int scsi_low_msgfunc_reset (struct scsi_low_softc *);
3247
3248 struct scsi_low_msgout_data {
3249         u_int   md_flags;
3250         u_int8_t md_msg;
3251         int (*md_msgfunc) (struct scsi_low_softc *);
3252         int (*md_errfunc) (struct scsi_low_softc *, u_int);
3253 #define MSG_RELEASE_ATN 0x0001
3254         u_int md_condition;
3255 };
3256
3257 struct scsi_low_msgout_data scsi_low_msgout_data[] = {
3258 /* 0 */ {SCSI_LOW_MSG_RESET, MSG_RESET, scsi_low_msgfunc_reset, NULL, MSG_RELEASE_ATN},
3259 /* 1 */ {SCSI_LOW_MSG_REJECT, MSG_REJECT, NULL, NULL, MSG_RELEASE_ATN},
3260 /* 2 */ {SCSI_LOW_MSG_PARITY, MSG_PARITY, NULL, NULL, MSG_RELEASE_ATN},
3261 /* 3 */ {SCSI_LOW_MSG_ERROR, MSG_I_ERROR, NULL, NULL, MSG_RELEASE_ATN},
3262 /* 4 */ {SCSI_LOW_MSG_IDENTIFY, MSG_IDENTIFY, scsi_low_msgfunc_identify, scsi_low_errfunc_identify, 0},
3263 /* 5 */ {SCSI_LOW_MSG_ABORT, MSG_ABORT, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3264 /* 6 */ {SCSI_LOW_MSG_TERMIO, MSG_TERM_IO, NULL, NULL, MSG_RELEASE_ATN},
3265 /* 7 */ {SCSI_LOW_MSG_SIMPLE_QTAG,  MSG_SIMPLE_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3266 /* 8 */ {SCSI_LOW_MSG_ORDERED_QTAG, MSG_ORDERED_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3267 /* 9 */{SCSI_LOW_MSG_HEAD_QTAG,  MSG_HEAD_QTAG, scsi_low_msgfunc_qtag, scsi_low_errfunc_qtag, 0},
3268 /* 10 */ {SCSI_LOW_MSG_ABORT_QTAG, MSG_ABORT_QTAG, scsi_low_msgfunc_qabort, NULL,  MSG_RELEASE_ATN},
3269 /* 11 */ {SCSI_LOW_MSG_CLEAR_QTAG, MSG_CLEAR_QTAG, scsi_low_msgfunc_abort, NULL, MSG_RELEASE_ATN},
3270 /* 12 */{SCSI_LOW_MSG_WIDE, MSG_EXTEND, scsi_low_msgfunc_wide, scsi_low_errfunc_wide, MSG_RELEASE_ATN},
3271 /* 13 */{SCSI_LOW_MSG_SYNCH, MSG_EXTEND, scsi_low_msgfunc_synch, scsi_low_errfunc_synch, MSG_RELEASE_ATN},
3272 /* 14 */{SCSI_LOW_MSG_NOOP, MSG_NOOP, NULL, NULL, MSG_RELEASE_ATN},
3273 /* 15 */{SCSI_LOW_MSG_ALL, 0},
3274 };
3275
3276 static int scsi_low_msginfunc_ext (struct scsi_low_softc *);
3277 static int scsi_low_synch (struct scsi_low_softc *);
3278 static int scsi_low_wide (struct scsi_low_softc *);
3279 static int scsi_low_msginfunc_msg_reject (struct scsi_low_softc *);
3280 static int scsi_low_msginfunc_rejop (struct scsi_low_softc *);
3281 static int scsi_low_msginfunc_rp (struct scsi_low_softc *);
3282 static int scsi_low_msginfunc_sdp (struct scsi_low_softc *);
3283 static int scsi_low_msginfunc_disc (struct scsi_low_softc *);
3284 static int scsi_low_msginfunc_cc (struct scsi_low_softc *);
3285 static int scsi_low_msginfunc_lcc (struct scsi_low_softc *);
3286 static int scsi_low_msginfunc_parity (struct scsi_low_softc *);
3287 static int scsi_low_msginfunc_noop (struct scsi_low_softc *);
3288 static int scsi_low_msginfunc_simple_qtag (struct scsi_low_softc *);
3289 static int scsi_low_msginfunc_i_wide_residue (struct scsi_low_softc *);
3290
3291 struct scsi_low_msgin_data {
3292         u_int md_len;
3293         int (*md_msgfunc) (struct scsi_low_softc *);
3294 };
3295
3296 struct scsi_low_msgin_data scsi_low_msgin_data[] = {
3297 /* 0 */ {1,     scsi_low_msginfunc_cc},
3298 /* 1 */ {2,     scsi_low_msginfunc_ext},
3299 /* 2 */ {1,     scsi_low_msginfunc_sdp},
3300 /* 3 */ {1,     scsi_low_msginfunc_rp},
3301 /* 4 */ {1,     scsi_low_msginfunc_disc},
3302 /* 5 */ {1,     scsi_low_msginfunc_rejop},
3303 /* 6 */ {1,     scsi_low_msginfunc_rejop},
3304 /* 7 */ {1,     scsi_low_msginfunc_msg_reject},
3305 /* 8 */ {1,     scsi_low_msginfunc_noop},
3306 /* 9 */ {1,     scsi_low_msginfunc_parity},
3307 /* a */ {1,     scsi_low_msginfunc_lcc},
3308 /* b */ {1,     scsi_low_msginfunc_lcc},
3309 /* c */ {1,     scsi_low_msginfunc_rejop},
3310 /* d */ {2,     scsi_low_msginfunc_rejop},
3311 /* e */ {1,     scsi_low_msginfunc_rejop},
3312 /* f */ {1,     scsi_low_msginfunc_rejop},
3313 /* 0x10 */ {1,  scsi_low_msginfunc_rejop},
3314 /* 0x11 */ {1,  scsi_low_msginfunc_rejop},
3315 /* 0x12 */ {1,  scsi_low_msginfunc_rejop},
3316 /* 0x13 */ {1,  scsi_low_msginfunc_rejop},
3317 /* 0x14 */ {1,  scsi_low_msginfunc_rejop},
3318 /* 0x15 */ {1,  scsi_low_msginfunc_rejop},
3319 /* 0x16 */ {1,  scsi_low_msginfunc_rejop},
3320 /* 0x17 */ {1,  scsi_low_msginfunc_rejop},
3321 /* 0x18 */ {1,  scsi_low_msginfunc_rejop},
3322 /* 0x19 */ {1,  scsi_low_msginfunc_rejop},
3323 /* 0x1a */ {1,  scsi_low_msginfunc_rejop},
3324 /* 0x1b */ {1,  scsi_low_msginfunc_rejop},
3325 /* 0x1c */ {1,  scsi_low_msginfunc_rejop},
3326 /* 0x1d */ {1,  scsi_low_msginfunc_rejop},
3327 /* 0x1e */ {1,  scsi_low_msginfunc_rejop},
3328 /* 0x1f */ {1,  scsi_low_msginfunc_rejop},
3329 /* 0x20 */ {2,  scsi_low_msginfunc_simple_qtag},
3330 /* 0x21 */ {2,  scsi_low_msginfunc_rejop},
3331 /* 0x22 */ {2,  scsi_low_msginfunc_rejop},
3332 /* 0x23 */ {2,  scsi_low_msginfunc_i_wide_residue},
3333 /* 0x24 */ {2,  scsi_low_msginfunc_rejop},
3334 /* 0x25 */ {2,  scsi_low_msginfunc_rejop},
3335 /* 0x26 */ {2,  scsi_low_msginfunc_rejop},
3336 /* 0x27 */ {2,  scsi_low_msginfunc_rejop},
3337 /* 0x28 */ {2,  scsi_low_msginfunc_rejop},
3338 /* 0x29 */ {2,  scsi_low_msginfunc_rejop},
3339 /* 0x2a */ {2,  scsi_low_msginfunc_rejop},
3340 /* 0x2b */ {2,  scsi_low_msginfunc_rejop},
3341 /* 0x2c */ {2,  scsi_low_msginfunc_rejop},
3342 /* 0x2d */ {2,  scsi_low_msginfunc_rejop},
3343 /* 0x2e */ {2,  scsi_low_msginfunc_rejop},
3344 /* 0x2f */ {2,  scsi_low_msginfunc_rejop},
3345 /* 0x30 */ {1,  scsi_low_msginfunc_rejop}       /* default rej op */
3346 };
3347
3348 /**************************************************************
3349  * msgout
3350  **************************************************************/
3351 static int
3352 scsi_low_msgfunc_synch(slp)
3353         struct scsi_low_softc *slp;
3354 {
3355         struct targ_info *ti = slp->sl_Tnexus;
3356         int ptr = ti->ti_msgoutlen;
3357
3358         ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_SYNCHLEN;
3359         ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_SYNCHCODE;
3360         ti->ti_msgoutstr[ptr + 3] = ti->ti_maxsynch.period;
3361         ti->ti_msgoutstr[ptr + 4] = ti->ti_maxsynch.offset;
3362         return MSG_EXTEND_SYNCHLEN + 2;
3363 }
3364
3365 static int
3366 scsi_low_msgfunc_wide(slp)
3367         struct scsi_low_softc *slp;
3368 {
3369         struct targ_info *ti = slp->sl_Tnexus;
3370         int ptr = ti->ti_msgoutlen;
3371
3372         ti->ti_msgoutstr[ptr + 1] = MSG_EXTEND_WIDELEN;
3373         ti->ti_msgoutstr[ptr + 2] = MSG_EXTEND_WIDECODE;
3374         ti->ti_msgoutstr[ptr + 3] = ti->ti_width;
3375         return MSG_EXTEND_WIDELEN + 2;
3376 }
3377
3378 static int
3379 scsi_low_msgfunc_identify(slp)
3380         struct scsi_low_softc *slp;
3381 {
3382         struct targ_info *ti = slp->sl_Tnexus;
3383         struct lun_info *li = slp->sl_Lnexus;
3384         struct slccb *cb = slp->sl_Qnexus;
3385         int ptr = ti->ti_msgoutlen;
3386         u_int8_t msg;
3387
3388         msg = MSG_IDENTIFY;
3389         if (cb == NULL)
3390         {
3391                 slp->sl_error |= FATALIO;
3392                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3393                 SCSI_LOW_INFO(slp, ti, "MSGOUT: nexus unknown");
3394         }
3395         else
3396         {
3397                 if (scsi_low_is_disconnect_ok(cb) != 0)
3398                         msg |= (MSG_IDENTIFY_DISCPRIV | li->li_lun);
3399                 else
3400                         msg |= li->li_lun;
3401
3402                 if (ti->ti_phase == PH_MSGOUT)
3403                 {
3404                         (*slp->sl_funcs->scsi_low_establish_lun_nexus) (slp);
3405                         if (cb->ccb_tag == SCSI_LOW_UNKTAG)
3406                         {
3407                                 (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3408                         }
3409                 }
3410         }
3411         ti->ti_msgoutstr[ptr + 0] = msg;
3412         return 1;
3413 }
3414
3415 static int
3416 scsi_low_msgfunc_abort(slp)
3417         struct scsi_low_softc *slp;
3418 {
3419
3420         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_ABORT);
3421         return 1;
3422 }
3423
3424 static int
3425 scsi_low_msgfunc_qabort(slp)
3426         struct scsi_low_softc *slp;
3427 {
3428
3429         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_TERM);
3430         return 1;
3431 }
3432
3433 static int
3434 scsi_low_msgfunc_reset(slp)
3435         struct scsi_low_softc *slp;
3436 {
3437
3438         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_RESET);
3439         return 1;
3440 }
3441
3442 static int
3443 scsi_low_msgfunc_qtag(slp)
3444         struct scsi_low_softc *slp;
3445 {
3446         struct targ_info *ti = slp->sl_Tnexus;
3447         struct slccb *cb = slp->sl_Qnexus;
3448         int ptr = ti->ti_msgoutlen;
3449
3450         if (cb == NULL || cb->ccb_tag == SCSI_LOW_UNKTAG)
3451         {
3452                 ti->ti_msgoutstr[ptr + 0] = MSG_NOOP;
3453                 return 1;
3454         }
3455         else
3456         {
3457                 ti->ti_msgoutstr[ptr + 1] = (u_int8_t) cb->ccb_tag;
3458                 if (ti->ti_phase == PH_MSGOUT)
3459                 {
3460                         (*slp->sl_funcs->scsi_low_establish_ccb_nexus) (slp);
3461                 }
3462         }
3463         return 2;
3464 }
3465
3466 /*
3467  * The following functions are called when targets give unexpected
3468  * responces in msgin (after msgout).
3469  */
3470 static int
3471 scsi_low_errfunc_identify(slp, msgflags)
3472         struct scsi_low_softc *slp;
3473         u_int msgflags;
3474 {
3475
3476         if (slp->sl_Lnexus != NULL)
3477         {
3478                 slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_DISC;
3479                 scsi_low_calcf_lun(slp->sl_Lnexus);
3480         }
3481         return 0;
3482 }
3483
3484 static int
3485 scsi_low_errfunc_synch(slp, msgflags)
3486         struct scsi_low_softc *slp;
3487         u_int msgflags;
3488 {
3489         struct targ_info *ti = slp->sl_Tnexus;
3490
3491         MSGIN_PERIOD(ti) = 0;
3492         MSGIN_OFFSET(ti) = 0;
3493         scsi_low_synch(slp);
3494         return 0;
3495 }
3496
3497 static int
3498 scsi_low_errfunc_wide(slp, msgflags)
3499         struct scsi_low_softc *slp;
3500         u_int msgflags;
3501 {
3502         struct targ_info *ti = slp->sl_Tnexus;
3503
3504         MSGIN_WIDTHP(ti) = 0;
3505         scsi_low_wide(slp);
3506         return 0;
3507 }
3508
3509 static int
3510 scsi_low_errfunc_qtag(slp, msgflags)
3511         struct scsi_low_softc *slp;
3512         u_int msgflags;
3513 {
3514
3515         if ((msgflags & SCSI_LOW_MSG_REJECT) != 0)
3516         {
3517                 if (slp->sl_Qnexus != NULL)
3518                 {
3519                         scsi_low_deactivate_qtag(slp->sl_Qnexus);
3520                 }
3521                 if (slp->sl_Lnexus != NULL)
3522                 {
3523                         slp->sl_Lnexus->li_cfgflags &= ~SCSI_LOW_QTAG;
3524                         scsi_low_calcf_lun(slp->sl_Lnexus);
3525                 }
3526                 printf("%s: scsi_low: qtag msg rejected\n", slp->sl_xname);
3527         }
3528         return 0;
3529 }
3530
3531
3532 int
3533 scsi_low_msgout(slp, ti, fl)
3534         struct scsi_low_softc *slp;
3535         struct targ_info *ti;
3536         u_int fl;
3537 {
3538         struct scsi_low_msgout_data *mdp;
3539         int len = 0;
3540
3541 #ifdef  SCSI_LOW_DIAGNOSTIC
3542         if (ti != slp->sl_Tnexus)
3543         {
3544                 scsi_low_print(slp, NULL);
3545                 panic("scsi_low_msgout: Target nexus inconsistent");
3546         }
3547 #endif  /* SCSI_LOW_DIAGNOSTIC */
3548
3549         slp->sl_ph_count ++;
3550         if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
3551         {
3552                 printf("%s: too many phase changes\n", slp->sl_xname);
3553                 slp->sl_error |= FATALIO;
3554                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3555         }
3556                 
3557         /* STEP I.
3558          * Scsi phase changes.
3559          * Previously msgs asserted are accepted by our target or
3560          * processed by scsi_low_msgin.
3561          * Thus clear all saved informations.
3562          */
3563         if ((fl & SCSI_LOW_MSGOUT_INIT) != 0)
3564         {
3565                 ti->ti_omsgflags = 0;
3566                 ti->ti_emsgflags = 0;
3567         }
3568         else if (slp->sl_atten == 0)
3569         {
3570         /* STEP II.
3571          * We did not assert attention, however still our target required
3572          * msgs. Resend previous msgs. 
3573          */
3574                 ti->ti_msgflags |= ti->ti_omsgflags;
3575                 ti->ti_omsgflags = 0;
3576 #ifdef  SCSI_LOW_DIAGNOSTIC
3577                 printf("%s: scsi_low_msgout: retry msgout\n", slp->sl_xname);
3578 #endif  /* SCSI_LOW_DIAGNOSTIC */
3579         }
3580
3581         /* STEP III.
3582          * We have no msgs. send MSG_NOOP (OK?)
3583          */
3584         if (scsi_low_is_msgout_continue(ti, 0) == 0)
3585                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_NOOP, 0);
3586
3587         /* STEP IV.
3588          * Process all msgs
3589          */
3590         ti->ti_msgoutlen = 0;
3591         slp->sl_clear_atten = 0;
3592         mdp = &scsi_low_msgout_data[0];
3593         for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
3594         {
3595                 if ((ti->ti_msgflags & mdp->md_flags) != 0)
3596                 {
3597                         ti->ti_omsgflags |= mdp->md_flags;
3598                         ti->ti_msgflags &= ~mdp->md_flags;
3599                         ti->ti_emsgflags = mdp->md_flags;
3600
3601                         ti->ti_msgoutstr[ti->ti_msgoutlen] = mdp->md_msg;
3602                         if (mdp->md_msgfunc != NULL)
3603                                 len = (*mdp->md_msgfunc) (slp);
3604                         else
3605                                 len = 1;
3606
3607 #ifdef  SCSI_LOW_DIAGNOSTIC
3608                         scsi_low_msg_log_write(&ti->ti_log_msgout,
3609                                &ti->ti_msgoutstr[ti->ti_msgoutlen], len);
3610 #endif  /* SCSI_LOW_DIAGNOSTIC */
3611
3612                         ti->ti_msgoutlen += len;
3613                         if ((mdp->md_condition & MSG_RELEASE_ATN) != 0)
3614                         {
3615                                 slp->sl_clear_atten = 1;
3616                                 break;
3617                         }
3618
3619                         if ((fl & SCSI_LOW_MSGOUT_UNIFY) == 0 ||
3620                             ti->ti_msgflags == 0)
3621                                 break;
3622
3623                         if (ti->ti_msgoutlen >= SCSI_LOW_MAX_MSGLEN - 5)
3624                                 break;
3625                 }
3626         }
3627
3628         if (scsi_low_is_msgout_continue(ti, 0) == 0)
3629                 slp->sl_clear_atten = 1;
3630
3631         return ti->ti_msgoutlen;
3632 }
3633
3634 /**************************************************************
3635  * msgin
3636  **************************************************************/
3637 static int
3638 scsi_low_msginfunc_noop(slp)
3639         struct scsi_low_softc *slp;
3640 {
3641
3642         return 0;
3643 }
3644
3645 static int
3646 scsi_low_msginfunc_rejop(slp)
3647         struct scsi_low_softc *slp;
3648 {
3649         struct targ_info *ti = slp->sl_Tnexus;
3650         u_int8_t msg = ti->ti_msgin[0];
3651
3652         printf("%s: MSGIN: msg 0x%x rejected\n", slp->sl_xname, (u_int) msg);
3653         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3654         return 0;
3655 }
3656
3657 static int
3658 scsi_low_msginfunc_cc(slp)
3659         struct scsi_low_softc *slp;
3660 {
3661         struct lun_info *li;
3662
3663         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_CMDC);
3664
3665         /* validate status */
3666         if (slp->sl_Qnexus == NULL)
3667                 return ENOENT;
3668
3669         slp->sl_Qnexus->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3670         li = slp->sl_Lnexus;
3671         switch (slp->sl_scp.scp_status)
3672         {
3673         case ST_GOOD:
3674                 li->li_maxnqio = li->li_maxnexus;
3675                 break;
3676
3677         case ST_CHKCOND:
3678                 li->li_maxnqio = 0;
3679                 if (li->li_qflags & SCSI_LOW_QFLAG_CA_QCLEAR)
3680                         scsi_low_reset_nexus_lun(slp, li, 0);
3681                 break;
3682
3683         case ST_BUSY:
3684                 li->li_maxnqio = 0;
3685                 break;
3686
3687         case ST_QUEFULL:
3688                 if (li->li_maxnexus >= li->li_nqio)
3689                         li->li_maxnexus = li->li_nqio - 1;
3690                 li->li_maxnqio = li->li_maxnexus;
3691                 break;
3692
3693         case ST_INTERGOOD:
3694         case ST_INTERMET:
3695                 slp->sl_error |= MSGERR;
3696                 break;
3697
3698         default:
3699                 break;
3700         }
3701         return 0;
3702 }
3703
3704 static int
3705 scsi_low_msginfunc_lcc(slp)
3706         struct scsi_low_softc *slp;
3707 {
3708         struct targ_info *ti;
3709         struct lun_info *li;
3710         struct slccb *ncb, *cb;
3711
3712         ti = slp->sl_Tnexus;
3713         li = slp->sl_Lnexus;
3714         if ((cb = slp->sl_Qnexus) == NULL)
3715                 goto bad;
3716                 
3717         cb->ccb_sscp.scp_status = slp->sl_scp.scp_status;
3718         switch (slp->sl_scp.scp_status)
3719         {
3720         case ST_INTERGOOD:
3721         case ST_INTERMET:
3722                 li->li_maxnqio = li->li_maxnexus;
3723                 break;
3724
3725         default:
3726                 slp->sl_error |= MSGERR;
3727                 break;
3728         }
3729
3730         if ((li->li_flags & SCSI_LOW_LINK) == 0)
3731                 goto bad;
3732
3733         cb->ccb_error |= slp->sl_error;
3734         if (cb->ccb_error != 0)
3735                 goto bad;
3736
3737         for (ncb = TAILQ_FIRST(&slp->sl_start); ncb != NULL;
3738              ncb = TAILQ_NEXT(ncb, ccb_chain))
3739         {
3740                 if (ncb->li == li)
3741                         goto cmd_link_start;
3742         }
3743
3744
3745 bad:
3746         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_LCTERM);
3747         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
3748         return EIO;
3749
3750 cmd_link_start:
3751         ncb->ccb_flags &= ~CCB_STARTQ;
3752         TAILQ_REMOVE(&slp->sl_start, ncb, ccb_chain);
3753
3754         scsi_low_dealloc_qtag(ncb);
3755         ncb->ccb_tag = cb->ccb_tag;
3756         ncb->ccb_otag = cb->ccb_otag;
3757         cb->ccb_tag = SCSI_LOW_UNKTAG;
3758         cb->ccb_otag = SCSI_LOW_UNKTAG;
3759         if (scsi_low_done(slp, cb) == SCSI_LOW_DONE_RETRY)
3760                 panic("%s: linked ccb retried", slp->sl_xname);
3761
3762         slp->sl_Qnexus = ncb;
3763         slp->sl_ph_count = 0;
3764
3765         ncb->ccb_error = 0;
3766         ncb->ccb_datalen = -1;
3767         ncb->ccb_scp.scp_status = ST_UNKNOWN;
3768         ncb->ccb_flags &= ~CCB_INTERNAL;
3769
3770         scsi_low_init_msgsys(slp, ti);
3771
3772         (*slp->sl_osdep_fp->scsi_low_osdep_ccb_setup) (slp, ncb);
3773
3774         if (ncb->ccb_tcmax < SCSI_LOW_MIN_TOUT)
3775                 ncb->ccb_tcmax = SCSI_LOW_MIN_TOUT;
3776         ncb->ccb_tc = ncb->ccb_tcmax;
3777
3778         /* setup saved scsi data pointer */
3779         ncb->ccb_sscp = ncb->ccb_scp;
3780         slp->sl_scp = ncb->ccb_sscp;
3781         slp->sl_error = ncb->ccb_error;
3782
3783 #ifdef  SCSI_LOW_DIAGNOSTIC
3784         scsi_low_msg_log_init(&ti->ti_log_msgin);
3785         scsi_low_msg_log_init(&ti->ti_log_msgout);
3786 #endif  /* SCSI_LOW_DIAGNOSTIC */
3787         return EJUSTRETURN;
3788 }
3789
3790 static int
3791 scsi_low_msginfunc_disc(slp)
3792         struct scsi_low_softc *slp;
3793 {
3794
3795         SCSI_LOW_SETUP_MSGPHASE(slp, MSGPH_DISC);
3796         return 0;
3797 }
3798
3799 static int
3800 scsi_low_msginfunc_sdp(slp)
3801         struct scsi_low_softc *slp;
3802 {
3803         struct slccb *cb = slp->sl_Qnexus;
3804
3805         if (cb != NULL)
3806         {
3807                 cb->ccb_sscp.scp_datalen = slp->sl_scp.scp_datalen;
3808                 cb->ccb_sscp.scp_data = slp->sl_scp.scp_data;
3809         }
3810         else
3811                 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3812         return 0;
3813 }
3814
3815 static int
3816 scsi_low_msginfunc_rp(slp)
3817         struct scsi_low_softc *slp;
3818 {
3819
3820         if (slp->sl_Qnexus != NULL)
3821                 slp->sl_scp = slp->sl_Qnexus->ccb_sscp;
3822         else
3823                 scsi_low_assert_msg(slp, slp->sl_Tnexus, SCSI_LOW_MSG_REJECT, 0);
3824         return 0;
3825 }
3826
3827 static int
3828 scsi_low_synch(slp)
3829         struct scsi_low_softc *slp;
3830 {
3831         struct targ_info *ti = slp->sl_Tnexus;
3832         u_int period = 0, offset = 0, speed;
3833         u_char *s;
3834         int error;
3835
3836         if ((MSGIN_PERIOD(ti) >= ti->ti_maxsynch.period &&
3837              MSGIN_OFFSET(ti) <= ti->ti_maxsynch.offset) ||
3838              MSGIN_OFFSET(ti) == 0)
3839         {
3840                 if ((offset = MSGIN_OFFSET(ti)) != 0)
3841                         period = MSGIN_PERIOD(ti);
3842                 s = offset ? "synchronous" : "async";
3843         }
3844         else
3845         {
3846                 /* XXX:
3847                  * Target seems to be brain damaged.
3848                  * Force async transfer.
3849                  */
3850                 ti->ti_maxsynch.period = 0;
3851                 ti->ti_maxsynch.offset = 0;
3852                 printf("%s: target brain damaged. async transfer\n",
3853                         slp->sl_xname);
3854                 return EINVAL;
3855         }
3856
3857         ti->ti_maxsynch.period = period;
3858         ti->ti_maxsynch.offset = offset;
3859
3860         error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_SYNCH);
3861         if (error != 0)
3862         {
3863                 /* XXX:
3864                  * Current period and offset are not acceptable 
3865                  * for our adapter.
3866                  * The adapter changes max synch and max offset.
3867                  */
3868                 printf("%s: synch neg failed. retry synch msg neg ...\n",
3869                         slp->sl_xname);
3870                 return error;
3871         }
3872
3873         ti->ti_osynch = ti->ti_maxsynch;
3874         if (offset > 0)
3875         {
3876                 ti->ti_setup_msg_done |= SCSI_LOW_MSG_SYNCH;
3877         }
3878
3879         /* inform data */
3880         if ((slp->sl_show_result & SHOW_SYNCH_NEG) != 0)
3881         {
3882 #ifdef  SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3883                 struct slccb *cb = slp->sl_Qnexus;
3884
3885                 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3886                         return 0;
3887 #endif  /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3888
3889                 printf("%s(%d:*): <%s> offset %d period %dns ",
3890                         slp->sl_xname, ti->ti_id, s, offset, period * 4);
3891
3892                 if (period != 0)
3893                 {
3894                         speed = 1000 * 10 / (period * 4);
3895                         printf("%d.%d M/s", speed / 10, speed % 10);
3896                 }
3897                 printf("\n");
3898         }
3899         return 0;
3900 }
3901
3902 static int
3903 scsi_low_wide(slp)
3904         struct scsi_low_softc *slp;
3905 {
3906         struct targ_info *ti = slp->sl_Tnexus;
3907         int error;
3908
3909         ti->ti_width = MSGIN_WIDTHP(ti);
3910         error = (*slp->sl_funcs->scsi_low_msg) (slp, ti, SCSI_LOW_MSG_WIDE);
3911         if (error != 0)
3912         {
3913                 /* XXX:
3914                  * Current width is not acceptable for our adapter.
3915                  * The adapter changes max width.
3916                  */
3917                 printf("%s: wide neg failed. retry wide msg neg ...\n",
3918                         slp->sl_xname);
3919                 return error;
3920         }
3921
3922         ti->ti_owidth = ti->ti_width;
3923         if (ti->ti_width > SCSI_LOW_BUS_WIDTH_8)
3924         {
3925                 ti->ti_setup_msg_done |= 
3926                         (SCSI_LOW_MSG_SYNCH | SCSI_LOW_MSG_WIDE);
3927         }
3928                 
3929         /* inform data */
3930         if ((slp->sl_show_result & SHOW_WIDE_NEG) != 0)
3931         {
3932 #ifdef  SCSI_LOW_NEGOTIATE_BEFORE_SENSE
3933                 struct slccb *cb = slp->sl_Qnexus;
3934
3935                 if (cb != NULL && (cb->ccb_flags & CCB_SENSE) != 0)
3936                         return 0;
3937 #endif  /* SCSI_LOW_NEGOTIATE_BEFORE_SENSE */
3938
3939                 printf("%s(%d:*): transfer width %d bits\n",
3940                         slp->sl_xname, ti->ti_id, 1 << (3 + ti->ti_width));
3941         }
3942         return 0;
3943 }
3944
3945 static int
3946 scsi_low_msginfunc_simple_qtag(slp)
3947         struct scsi_low_softc *slp;
3948 {
3949         struct targ_info *ti = slp->sl_Tnexus;
3950         scsi_low_tag_t etag = (scsi_low_tag_t) ti->ti_msgin[1];
3951
3952         if (slp->sl_Qnexus != NULL)
3953         {
3954                 if (slp->sl_Qnexus->ccb_tag != etag)
3955                 {
3956                         slp->sl_error |= FATALIO;
3957                         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
3958                         SCSI_LOW_INFO(slp, ti, "MSGIN: qtag mismatch");
3959                 }
3960         }
3961         else if (scsi_low_establish_ccb(ti, slp->sl_Lnexus, etag) == NULL)
3962         {
3963 #ifdef  SCSI_LOW_DEBUG
3964                 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_NEXUS_CHECK, ti->ti_id))
3965                         return 0;
3966 #endif  /* SCSI_LOW_DEBUG */
3967
3968                 slp->sl_error |= FATALIO;
3969                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT_QTAG, 0);
3970                 SCSI_LOW_INFO(slp, ti, "MSGIN: taged ccb not found");
3971         }
3972         return 0;
3973 }
3974
3975 static int
3976 scsi_low_msginfunc_i_wide_residue(slp)
3977         struct scsi_low_softc *slp;
3978 {
3979         struct targ_info *ti = slp->sl_Tnexus;
3980         struct slccb *cb = slp->sl_Qnexus;
3981         int res = (int) ti->ti_msgin[1];
3982
3983         if (cb == NULL || res <= 0 ||
3984             (ti->ti_width == SCSI_LOW_BUS_WIDTH_16 && res > 1) ||
3985             (ti->ti_width == SCSI_LOW_BUS_WIDTH_32 && res > 3))
3986                 return EINVAL;
3987                 
3988         if (slp->sl_scp.scp_datalen + res > cb->ccb_scp.scp_datalen)
3989                 return EINVAL;
3990
3991         slp->sl_scp.scp_datalen += res;
3992         slp->sl_scp.scp_data -= res;
3993         scsi_low_data_finish(slp);
3994         return 0;
3995 }
3996
3997 static int
3998 scsi_low_msginfunc_ext(slp)
3999         struct scsi_low_softc *slp;
4000 {
4001         struct slccb *cb = slp->sl_Qnexus;
4002         struct lun_info *li = slp->sl_Lnexus;
4003         struct targ_info *ti = slp->sl_Tnexus;
4004         int count, retry;
4005         u_int32_t *ptr;
4006
4007         if (ti->ti_msginptr == 2)
4008         {
4009                 ti->ti_msginlen = ti->ti_msgin[1] + 2;
4010                 return 0;
4011         }
4012
4013         switch (MKMSG_EXTEND(ti->ti_msgin[1], ti->ti_msgin[2]))
4014         {
4015         case MKMSG_EXTEND(MSG_EXTEND_MDPLEN, MSG_EXTEND_MDPCODE):
4016                 if (cb == NULL)
4017                         break;
4018
4019                 ptr = (u_int32_t *)(&ti->ti_msgin[3]);
4020                 count = (int) htonl((long) (*ptr));
4021                 if(slp->sl_scp.scp_datalen - count < 0 || 
4022                    slp->sl_scp.scp_datalen - count > cb->ccb_scp.scp_datalen)
4023                         break;
4024
4025                 slp->sl_scp.scp_datalen -= count;
4026                 slp->sl_scp.scp_data += count;
4027                 return 0;
4028
4029         case MKMSG_EXTEND(MSG_EXTEND_SYNCHLEN, MSG_EXTEND_SYNCHCODE):
4030                 if (li == NULL)
4031                         break;
4032
4033                 retry = scsi_low_synch(slp);
4034                 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_SYNCH) == 0)
4035                         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_SYNCH, 0);
4036
4037 #ifdef  SCSI_LOW_DEBUG
4038                 if (SCSI_LOW_DEBUG_TEST_GO(SCSI_LOW_ATTEN_CHECK, ti->ti_id))
4039                 {
4040                         scsi_low_test_atten(slp, ti, SCSI_LOW_MSG_SYNCH);
4041                 }
4042 #endif  /* SCSI_LOW_DEBUG */
4043                 return 0;
4044
4045         case MKMSG_EXTEND(MSG_EXTEND_WIDELEN, MSG_EXTEND_WIDECODE):
4046                 if (li == NULL)
4047                         break;
4048
4049                 retry = scsi_low_wide(slp);
4050                 if (retry != 0 || (ti->ti_emsgflags & SCSI_LOW_MSG_WIDE) == 0)
4051                         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_WIDE, 0);
4052
4053                 return 0;
4054
4055         default:
4056                 break;
4057         }
4058
4059         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4060         return EINVAL;
4061 }
4062
4063 static int
4064 scsi_low_msginfunc_parity(slp)
4065         struct scsi_low_softc *slp;
4066 {
4067         struct targ_info *ti = slp->sl_Tnexus;
4068
4069         /* only I -> T, invalid! */
4070         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4071         return 0;
4072 }
4073
4074 static int
4075 scsi_low_msginfunc_msg_reject(slp)
4076         struct scsi_low_softc *slp;
4077 {
4078         struct targ_info *ti = slp->sl_Tnexus;
4079         struct scsi_low_msgout_data *mdp;
4080         u_int msgflags;
4081
4082         if (ti->ti_emsgflags != 0)
4083         {
4084                 printf("%s: msg flags [0x%x] rejected\n",
4085                        slp->sl_xname, ti->ti_emsgflags);
4086                 msgflags = SCSI_LOW_MSG_REJECT;
4087                 mdp = &scsi_low_msgout_data[0];
4088                 for ( ; mdp->md_flags != SCSI_LOW_MSG_ALL; mdp ++)
4089                 {
4090                         if ((ti->ti_emsgflags & mdp->md_flags) != 0)
4091                         {
4092                                 ti->ti_emsgflags &= ~mdp->md_flags;
4093                                 if (mdp->md_errfunc != NULL)
4094                                         (*mdp->md_errfunc) (slp, msgflags);
4095                                 break;
4096                         }
4097                 }
4098                 return 0;
4099         }
4100         else
4101         {
4102                 SCSI_LOW_INFO(slp, ti, "MSGIN: rejected msg not found");
4103                 slp->sl_error |= MSGERR;
4104         }
4105         return EINVAL;
4106 }
4107
4108 int
4109 scsi_low_msgin(slp, ti, c)
4110         struct scsi_low_softc *slp;
4111         struct targ_info *ti;
4112         u_int c;
4113 {
4114         struct scsi_low_msgin_data *sdp;
4115         struct lun_info *li;
4116         u_int8_t msg;
4117
4118 #ifdef  SCSI_LOW_DIAGNOSTIC
4119         if (ti != slp->sl_Tnexus)
4120         {
4121                 scsi_low_print(slp, NULL);
4122                 panic("scsi_low_msgin: Target nexus inconsistent");
4123         }
4124 #endif  /* SCSI_LOW_DIAGNOSTIC */
4125
4126         /*
4127          * Phase changes, clear the pointer.
4128          */
4129         if (ti->ti_ophase != ti->ti_phase)
4130         {
4131                 MSGINPTR_CLR(ti);
4132                 ti->ti_msgin_parity_error = 0;
4133
4134                 slp->sl_ph_count ++;
4135                 if (slp->sl_ph_count > SCSI_LOW_MAX_PHCHANGES)
4136                 {
4137                         printf("%s: too many phase changes\n", slp->sl_xname);
4138                         slp->sl_error |= FATALIO;
4139                         scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_ABORT, 0);
4140                 }
4141         }
4142
4143         /*
4144          * Store a current messages byte into buffer and 
4145          * wait for the completion of the current msg.
4146          */
4147         ti->ti_msgin[ti->ti_msginptr ++] = (u_int8_t) c;
4148         if (ti->ti_msginptr >= SCSI_LOW_MAX_MSGLEN)
4149         {
4150                 ti->ti_msginptr = SCSI_LOW_MAX_MSGLEN - 1;
4151                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_REJECT, 0);
4152         }       
4153
4154         /*
4155          * Check parity errors.
4156          */
4157         if ((c & SCSI_LOW_DATA_PE) != 0)
4158         {
4159                 ti->ti_msgin_parity_error ++;
4160                 scsi_low_assert_msg(slp, ti, SCSI_LOW_MSG_PARITY, 0);
4161                 goto out;
4162         }
4163
4164         if (ti->ti_msgin_parity_error != 0)
4165                 goto out;
4166
4167         /*
4168          * Calculate messages length.
4169         &n