The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/cam/scsi/scsi_low.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 27778d715fdec0a0b4b39964a0a6e674


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.