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