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

Cache object: 623db91bd5f89c4cd6e3645058bbe60f


[ 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.