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

Cache object: 0f4be65eefab57649e2942d02bf66fa1


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