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

FreeBSD/Linux Kernel Cross Reference
sys/cam/cam_xpt.c

Version: -  FREEBSD  -  FREEBSD8  -  FREEBSD7  -  FREEBSD72  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  OPENSOLARIS  -  minix-3-1-1  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

    1 /*-
    2  * Implementation of the Common Access Method Transport (XPT) layer.
    3  *
    4  * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
    5  * Copyright (c) 1997, 1998, 1999 Kenneth D. Merry.
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions, and the following disclaimer,
   13  *    without modification, immediately at the beginning of the file.
   14  * 2. The name of the author may not be used to endorse or promote products
   15  *    derived from this software without specific prior written permission.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
   21  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD: head/sys/cam/cam_xpt.c 199280 2009-11-14 20:23:20Z mav $");
   32 
   33 #include <sys/param.h>
   34 #include <sys/bus.h>
   35 #include <sys/systm.h>
   36 #include <sys/types.h>
   37 #include <sys/malloc.h>
   38 #include <sys/kernel.h>
   39 #include <sys/time.h>
   40 #include <sys/conf.h>
   41 #include <sys/fcntl.h>
   42 #include <sys/md5.h>
   43 #include <sys/interrupt.h>
   44 #include <sys/sbuf.h>
   45 #include <sys/taskqueue.h>
   46 
   47 #include <sys/lock.h>
   48 #include <sys/mutex.h>
   49 #include <sys/sysctl.h>
   50 #include <sys/kthread.h>
   51 
   52 #ifdef PC98
   53 #include <pc98/pc98/pc98_machdep.h>     /* geometry translation */
   54 #endif
   55 
   56 #include <cam/cam.h>
   57 #include <cam/cam_ccb.h>
   58 #include <cam/cam_periph.h>
   59 #include <cam/cam_queue.h>
   60 #include <cam/cam_sim.h>
   61 #include <cam/cam_xpt.h>
   62 #include <cam/cam_xpt_sim.h>
   63 #include <cam/cam_xpt_periph.h>
   64 #include <cam/cam_xpt_internal.h>
   65 #include <cam/cam_debug.h>
   66 
   67 #include <cam/scsi/scsi_all.h>
   68 #include <cam/scsi/scsi_message.h>
   69 #include <cam/scsi/scsi_pass.h>
   70 #include <machine/stdarg.h>     /* for xpt_print below */
   71 #include "opt_cam.h"
   72 
   73 /*
   74  * This is the maximum number of high powered commands (e.g. start unit)
   75  * that can be outstanding at a particular time.
   76  */
   77 #ifndef CAM_MAX_HIGHPOWER
   78 #define CAM_MAX_HIGHPOWER  4
   79 #endif
   80 
   81 /* Datastructures internal to the xpt layer */
   82 MALLOC_DEFINE(M_CAMXPT, "CAM XPT", "CAM XPT buffers");
   83 
   84 /* Object for defering XPT actions to a taskqueue */
   85 struct xpt_task {
   86         struct task     task;
   87         void            *data1;
   88         uintptr_t       data2;
   89 };
   90 
   91 typedef enum {
   92         XPT_FLAG_OPEN           = 0x01
   93 } xpt_flags;
   94 
   95 struct xpt_softc {
   96         xpt_flags               flags;
   97         u_int32_t               xpt_generation;
   98 
   99         /* number of high powered commands that can go through right now */
  100         STAILQ_HEAD(highpowerlist, ccb_hdr)     highpowerq;
  101         int                     num_highpower;
  102 
  103         /* queue for handling async rescan requests. */
  104         TAILQ_HEAD(, ccb_hdr) ccb_scanq;
  105 
  106         /* Registered busses */
  107         TAILQ_HEAD(,cam_eb)     xpt_busses;
  108         u_int                   bus_generation;
  109 
  110         struct intr_config_hook *xpt_config_hook;
  111 
  112         struct mtx              xpt_topo_lock;
  113         struct mtx              xpt_lock;
  114 };
  115 
  116 typedef enum {
  117         DM_RET_COPY             = 0x01,
  118         DM_RET_FLAG_MASK        = 0x0f,
  119         DM_RET_NONE             = 0x00,
  120         DM_RET_STOP             = 0x10,
  121         DM_RET_DESCEND          = 0x20,
  122         DM_RET_ERROR            = 0x30,
  123         DM_RET_ACTION_MASK      = 0xf0
  124 } dev_match_ret;
  125 
  126 typedef enum {
  127         XPT_DEPTH_BUS,
  128         XPT_DEPTH_TARGET,
  129         XPT_DEPTH_DEVICE,
  130         XPT_DEPTH_PERIPH
  131 } xpt_traverse_depth;
  132 
  133 struct xpt_traverse_config {
  134         xpt_traverse_depth      depth;
  135         void                    *tr_func;
  136         void                    *tr_arg;
  137 };
  138 
  139 typedef int     xpt_busfunc_t (struct cam_eb *bus, void *arg);
  140 typedef int     xpt_targetfunc_t (struct cam_et *target, void *arg);
  141 typedef int     xpt_devicefunc_t (struct cam_ed *device, void *arg);
  142 typedef int     xpt_periphfunc_t (struct cam_periph *periph, void *arg);
  143 typedef int     xpt_pdrvfunc_t (struct periph_driver **pdrv, void *arg);
  144 
  145 /* Transport layer configuration information */
  146 static struct xpt_softc xsoftc;
  147 
  148 /* Queues for our software interrupt handler */
  149 typedef TAILQ_HEAD(cam_isrq, ccb_hdr) cam_isrq_t;
  150 typedef TAILQ_HEAD(cam_simq, cam_sim) cam_simq_t;
  151 static cam_simq_t cam_simq;
  152 static struct mtx cam_simq_lock;
  153 
  154 /* Pointers to software interrupt handlers */
  155 static void *cambio_ih;
  156 
  157 struct cam_periph *xpt_periph;
  158 
  159 static periph_init_t xpt_periph_init;
  160 
  161 static struct periph_driver xpt_driver =
  162 {
  163         xpt_periph_init, "xpt",
  164         TAILQ_HEAD_INITIALIZER(xpt_driver.units), /* generation */ 0,
  165         CAM_PERIPH_DRV_EARLY
  166 };
  167 
  168 PERIPHDRIVER_DECLARE(xpt, xpt_driver);
  169 
  170 static d_open_t xptopen;
  171 static d_close_t xptclose;
  172 static d_ioctl_t xptioctl;
  173 
  174 static struct cdevsw xpt_cdevsw = {
  175         .d_version =    D_VERSION,
  176         .d_flags =      0,
  177         .d_open =       xptopen,
  178         .d_close =      xptclose,
  179         .d_ioctl =      xptioctl,
  180         .d_name =       "xpt",
  181 };
  182 
  183 /* Storage for debugging datastructures */
  184 #ifdef  CAMDEBUG
  185 struct cam_path *cam_dpath;
  186 u_int32_t cam_dflags;
  187 u_int32_t cam_debug_delay;
  188 #endif
  189 
  190 /* Our boot-time initialization hook */
  191 static int cam_module_event_handler(module_t, int /*modeventtype_t*/, void *);
  192 
  193 static moduledata_t cam_moduledata = {
  194         "cam",
  195         cam_module_event_handler,
  196         NULL
  197 };
  198 
  199 static int      xpt_init(void *);
  200 
  201 DECLARE_MODULE(cam, cam_moduledata, SI_SUB_CONFIGURE, SI_ORDER_SECOND);
  202 MODULE_VERSION(cam, 1);
  203 
  204 
  205 static void             xpt_async_bcast(struct async_list *async_head,
  206                                         u_int32_t async_code,
  207                                         struct cam_path *path,
  208                                         void *async_arg);
  209 static path_id_t xptnextfreepathid(void);
  210 static path_id_t xptpathid(const char *sim_name, int sim_unit, int sim_bus);
  211 static union ccb *xpt_get_ccb(struct cam_ed *device);
  212 static void      xpt_run_dev_allocq(struct cam_eb *bus);
  213 static timeout_t xpt_release_devq_timeout;
  214 static void      xpt_release_simq_timeout(void *arg) __unused;
  215 static void      xpt_release_bus(struct cam_eb *bus);
  216 static void      xpt_release_devq_device(struct cam_ed *dev, u_int count,
  217                                          int run_queue);
  218 static struct cam_et*
  219                  xpt_alloc_target(struct cam_eb *bus, target_id_t target_id);
  220 static void      xpt_release_target(struct cam_et *target);
  221 static struct cam_eb*
  222                  xpt_find_bus(path_id_t path_id);
  223 static struct cam_et*
  224                  xpt_find_target(struct cam_eb *bus, target_id_t target_id);
  225 static struct cam_ed*
  226                  xpt_find_device(struct cam_et *target, lun_id_t lun_id);
  227 static xpt_busfunc_t    xptconfigbuscountfunc;
  228 static xpt_busfunc_t    xptconfigfunc;
  229 static void      xpt_config(void *arg);
  230 static xpt_devicefunc_t xptpassannouncefunc;
  231 static void      xpt_finishconfig(struct cam_periph *periph, union ccb *ccb);
  232 static void      xptaction(struct cam_sim *sim, union ccb *work_ccb);
  233 static void      xptpoll(struct cam_sim *sim);
  234 static void      camisr(void *);
  235 static void      camisr_runqueue(void *);
  236 static dev_match_ret    xptbusmatch(struct dev_match_pattern *patterns,
  237                                     u_int num_patterns, struct cam_eb *bus);
  238 static dev_match_ret    xptdevicematch(struct dev_match_pattern *patterns,
  239                                        u_int num_patterns,
  240                                        struct cam_ed *device);
  241 static dev_match_ret    xptperiphmatch(struct dev_match_pattern *patterns,
  242                                        u_int num_patterns,
  243                                        struct cam_periph *periph);
  244 static xpt_busfunc_t    xptedtbusfunc;
  245 static xpt_targetfunc_t xptedttargetfunc;
  246 static xpt_devicefunc_t xptedtdevicefunc;
  247 static xpt_periphfunc_t xptedtperiphfunc;
  248 static xpt_pdrvfunc_t   xptplistpdrvfunc;
  249 static xpt_periphfunc_t xptplistperiphfunc;
  250 static int              xptedtmatch(struct ccb_dev_match *cdm);
  251 static int              xptperiphlistmatch(struct ccb_dev_match *cdm);
  252 static int              xptbustraverse(struct cam_eb *start_bus,
  253                                        xpt_busfunc_t *tr_func, void *arg);
  254 static int              xpttargettraverse(struct cam_eb *bus,
  255                                           struct cam_et *start_target,
  256                                           xpt_targetfunc_t *tr_func, void *arg);
  257 static int              xptdevicetraverse(struct cam_et *target,
  258                                           struct cam_ed *start_device,
  259                                           xpt_devicefunc_t *tr_func, void *arg);
  260 static int              xptperiphtraverse(struct cam_ed *device,
  261                                           struct cam_periph *start_periph,
  262                                           xpt_periphfunc_t *tr_func, void *arg);
  263 static int              xptpdrvtraverse(struct periph_driver **start_pdrv,
  264                                         xpt_pdrvfunc_t *tr_func, void *arg);
  265 static int              xptpdperiphtraverse(struct periph_driver **pdrv,
  266                                             struct cam_periph *start_periph,
  267                                             xpt_periphfunc_t *tr_func,
  268                                             void *arg);
  269 static xpt_busfunc_t    xptdefbusfunc;
  270 static xpt_targetfunc_t xptdeftargetfunc;
  271 static xpt_devicefunc_t xptdefdevicefunc;
  272 static xpt_periphfunc_t xptdefperiphfunc;
  273 static int              xpt_for_all_busses(xpt_busfunc_t *tr_func, void *arg);
  274 static int              xpt_for_all_devices(xpt_devicefunc_t *tr_func,
  275                                             void *arg);
  276 static void             xpt_dev_async_default(u_int32_t async_code,
  277                                               struct cam_eb *bus,
  278                                               struct cam_et *target,
  279                                               struct cam_ed *device,
  280                                               void *async_arg);
  281 static struct cam_ed *  xpt_alloc_device_default(struct cam_eb *bus,
  282                                                  struct cam_et *target,
  283                                                  lun_id_t lun_id);
  284 static xpt_devicefunc_t xptsetasyncfunc;
  285 static xpt_busfunc_t    xptsetasyncbusfunc;
  286 static cam_status       xptregister(struct cam_periph *periph,
  287                                     void *arg);
  288 static __inline int xpt_schedule_dev_allocq(struct cam_eb *bus,
  289                                             struct cam_ed *dev);
  290 static __inline int periph_is_queued(struct cam_periph *periph);
  291 static __inline int device_is_alloc_queued(struct cam_ed *device);
  292 static __inline int device_is_send_queued(struct cam_ed *device);
  293 static __inline int dev_allocq_is_runnable(struct cam_devq *devq);
  294 
  295 static __inline int
  296 xpt_schedule_dev_allocq(struct cam_eb *bus, struct cam_ed *dev)
  297 {
  298         int retval;
  299 
  300         if (dev->ccbq.devq_openings > 0) {
  301                 /*
  302                  * The priority of a device waiting for CCB resources
  303                  * is that of the the highest priority peripheral driver
  304                  * enqueued.
  305                  */
  306                 retval = xpt_schedule_dev(&bus->sim->devq->alloc_queue,
  307                                           &dev->alloc_ccb_entry.pinfo,
  308                                           CAMQ_GET_HEAD(&dev->drvq)->priority);
  309         } else {
  310                 retval = 0;
  311         }
  312 
  313         return (retval);
  314 }
  315 
  316 static __inline int
  317 xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev)
  318 {
  319         int     retval;
  320 
  321         if (dev->ccbq.dev_openings > 0) {
  322                 /*
  323                  * The priority of a device waiting for controller
  324                  * resources is that of the the highest priority CCB
  325                  * enqueued.
  326                  */
  327                 retval =
  328                     xpt_schedule_dev(&bus->sim->devq->send_queue,
  329                                      &dev->send_ccb_entry.pinfo,
  330                                      CAMQ_GET_HEAD(&dev->ccbq.queue)->priority);
  331         } else {
  332                 retval = 0;
  333         }
  334         return (retval);
  335 }
  336 
  337 static __inline int
  338 periph_is_queued(struct cam_periph *periph)
  339 {
  340         return (periph->pinfo.index != CAM_UNQUEUED_INDEX);
  341 }
  342 
  343 static __inline int
  344 device_is_alloc_queued(struct cam_ed *device)
  345 {
  346         return (device->alloc_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX);
  347 }
  348 
  349 static __inline int
  350 device_is_send_queued(struct cam_ed *device)
  351 {
  352         return (device->send_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX);
  353 }
  354 
  355 static __inline int
  356 dev_allocq_is_runnable(struct cam_devq *devq)
  357 {
  358         /*
  359          * Have work to do.
  360          * Have space to do more work.
  361          * Allowed to do work.
  362          */
  363         return ((devq->alloc_queue.qfrozen_cnt == 0)
  364              && (devq->alloc_queue.entries > 0)
  365              && (devq->alloc_openings > 0));
  366 }
  367 
  368 static void
  369 xpt_periph_init()
  370 {
  371         make_dev(&xpt_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0600, "xpt0");
  372 }
  373 
  374 static void
  375 xptdone(struct cam_periph *periph, union ccb *done_ccb)
  376 {
  377         /* Caller will release the CCB */
  378         wakeup(&done_ccb->ccb_h.cbfcnp);
  379 }
  380 
  381 static int
  382 xptopen(struct cdev *dev, int flags, int fmt, struct thread *td)
  383 {
  384 
  385         /*
  386          * Only allow read-write access.
  387          */
  388         if (((flags & FWRITE) == 0) || ((flags & FREAD) == 0))
  389                 return(EPERM);
  390 
  391         /*
  392          * We don't allow nonblocking access.
  393          */
  394         if ((flags & O_NONBLOCK) != 0) {
  395                 printf("%s: can't do nonblocking access\n", devtoname(dev));
  396                 return(ENODEV);
  397         }
  398 
  399         /* Mark ourselves open */
  400         mtx_lock(&xsoftc.xpt_lock);
  401         xsoftc.flags |= XPT_FLAG_OPEN;
  402         mtx_unlock(&xsoftc.xpt_lock);
  403 
  404         return(0);
  405 }
  406 
  407 static int
  408 xptclose(struct cdev *dev, int flag, int fmt, struct thread *td)
  409 {
  410 
  411         /* Mark ourselves closed */
  412         mtx_lock(&xsoftc.xpt_lock);
  413         xsoftc.flags &= ~XPT_FLAG_OPEN;
  414         mtx_unlock(&xsoftc.xpt_lock);
  415 
  416         return(0);
  417 }
  418 
  419 /*
  420  * Don't automatically grab the xpt softc lock here even though this is going
  421  * through the xpt device.  The xpt device is really just a back door for
  422  * accessing other devices and SIMs, so the right thing to do is to grab
  423  * the appropriate SIM lock once the bus/SIM is located.
  424  */
  425 static int
  426 xptioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
  427 {
  428         int error;
  429 
  430         error = 0;
  431 
  432         switch(cmd) {
  433         /*
  434          * For the transport layer CAMIOCOMMAND ioctl, we really only want
  435          * to accept CCB types that don't quite make sense to send through a
  436          * passthrough driver. XPT_PATH_INQ is an exception to this, as stated
  437          * in the CAM spec.
  438          */
  439         case CAMIOCOMMAND: {
  440                 union ccb *ccb;
  441                 union ccb *inccb;
  442                 struct cam_eb *bus;
  443 
  444                 inccb = (union ccb *)addr;
  445 
  446                 bus = xpt_find_bus(inccb->ccb_h.path_id);
  447                 if (bus == NULL) {
  448                         error = EINVAL;
  449                         break;
  450                 }
  451 
  452                 switch(inccb->ccb_h.func_code) {
  453                 case XPT_SCAN_BUS:
  454                 case XPT_RESET_BUS:
  455                         if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD)
  456                          || (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD)) {
  457                                 error = EINVAL;
  458                                 break;
  459                         }
  460                         /* FALLTHROUGH */
  461                 case XPT_PATH_INQ:
  462                 case XPT_ENG_INQ:
  463                 case XPT_SCAN_LUN:
  464 
  465                         ccb = xpt_alloc_ccb();
  466 
  467                         CAM_SIM_LOCK(bus->sim);
  468                         /* Ensure passed in target/lun supported on this bus. */
  469                         if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD) ||
  470                             (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD)) {
  471                                 if (xpt_create_path(&ccb->ccb_h.path,
  472                                             xpt_periph,
  473                                             inccb->ccb_h.path_id,
  474                                             CAM_TARGET_WILDCARD,
  475                                             CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
  476                                         error = EINVAL;
  477                                         CAM_SIM_UNLOCK(bus->sim);
  478                                         xpt_free_ccb(ccb);
  479                                         break;
  480                                 }
  481                                 xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path,
  482                                     inccb->ccb_h.pinfo.priority);
  483                                 ccb->ccb_h.func_code = XPT_PATH_INQ;
  484                                 xpt_action(ccb);
  485                                 xpt_free_path(ccb->ccb_h.path);
  486                                 if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD &&
  487                                     inccb->ccb_h.target_id > ccb->cpi.max_target) ||
  488                                     (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD &&
  489                                     inccb->ccb_h.target_lun > ccb->cpi.max_lun)) {
  490                                         error = EINVAL;
  491                                         CAM_SIM_UNLOCK(bus->sim);
  492                                         xpt_free_ccb(ccb);
  493                                         break;
  494                                 }
  495                         }
  496                         /*
  497                          * Create a path using the bus, target, and lun the
  498                          * user passed in.
  499                          */
  500                         if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
  501                                             inccb->ccb_h.path_id,
  502                                             inccb->ccb_h.target_id,
  503                                             inccb->ccb_h.target_lun) !=
  504                                             CAM_REQ_CMP){
  505                                 error = EINVAL;
  506                                 CAM_SIM_UNLOCK(bus->sim);
  507                                 xpt_free_ccb(ccb);
  508                                 break;
  509                         }
  510                         /* Ensure all of our fields are correct */
  511                         xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path,
  512                                       inccb->ccb_h.pinfo.priority);
  513                         xpt_merge_ccb(ccb, inccb);
  514                         ccb->ccb_h.cbfcnp = xptdone;
  515                         cam_periph_runccb(ccb, NULL, 0, 0, NULL);
  516                         bcopy(ccb, inccb, sizeof(union ccb));
  517                         xpt_free_path(ccb->ccb_h.path);
  518                         xpt_free_ccb(ccb);
  519                         CAM_SIM_UNLOCK(bus->sim);
  520                         break;
  521 
  522                 case XPT_DEBUG: {
  523                         union ccb ccb;
  524 
  525                         /*
  526                          * This is an immediate CCB, so it's okay to
  527                          * allocate it on the stack.
  528                          */
  529 
  530                         CAM_SIM_LOCK(bus->sim);
  531 
  532                         /*
  533                          * Create a path using the bus, target, and lun the
  534                          * user passed in.
  535                          */
  536                         if (xpt_create_path(&ccb.ccb_h.path, xpt_periph,
  537                                             inccb->ccb_h.path_id,
  538                                             inccb->ccb_h.target_id,
  539                                             inccb->ccb_h.target_lun) !=
  540                                             CAM_REQ_CMP){
  541                                 error = EINVAL;
  542                                 CAM_SIM_UNLOCK(bus->sim);
  543                                 break;
  544                         }
  545                         /* Ensure all of our fields are correct */
  546                         xpt_setup_ccb(&ccb.ccb_h, ccb.ccb_h.path,
  547                                       inccb->ccb_h.pinfo.priority);
  548                         xpt_merge_ccb(&ccb, inccb);
  549                         ccb.ccb_h.cbfcnp = xptdone;
  550                         xpt_action(&ccb);
  551                         CAM_SIM_UNLOCK(bus->sim);
  552                         bcopy(&ccb, inccb, sizeof(union ccb));
  553                         xpt_free_path(ccb.ccb_h.path);
  554                         break;
  555 
  556                 }
  557                 case XPT_DEV_MATCH: {
  558                         struct cam_periph_map_info mapinfo;
  559                         struct cam_path *old_path;
  560 
  561                         /*
  562                          * We can't deal with physical addresses for this
  563                          * type of transaction.
  564                          */
  565                         if (inccb->ccb_h.flags & CAM_DATA_PHYS) {
  566                                 error = EINVAL;
  567                                 break;
  568                         }
  569 
  570                         /*
  571                          * Save this in case the caller had it set to
  572                          * something in particular.
  573                          */
  574                         old_path = inccb->ccb_h.path;
  575 
  576                         /*
  577                          * We really don't need a path for the matching
  578                          * code.  The path is needed because of the
  579                          * debugging statements in xpt_action().  They
  580                          * assume that the CCB has a valid path.
  581                          */
  582                         inccb->ccb_h.path = xpt_periph->path;
  583 
  584                         bzero(&mapinfo, sizeof(mapinfo));
  585 
  586                         /*
  587                          * Map the pattern and match buffers into kernel
  588                          * virtual address space.
  589                          */
  590                         error = cam_periph_mapmem(inccb, &mapinfo);
  591 
  592                         if (error) {
  593                                 inccb->ccb_h.path = old_path;
  594                                 break;
  595                         }
  596 
  597                         /*
  598                          * This is an immediate CCB, we can send it on directly.
  599                          */
  600                         xpt_action(inccb);
  601 
  602                         /*
  603                          * Map the buffers back into user space.
  604                          */
  605                         cam_periph_unmapmem(inccb, &mapinfo);
  606 
  607                         inccb->ccb_h.path = old_path;
  608 
  609                         error = 0;
  610                         break;
  611                 }
  612                 default:
  613                         error = ENOTSUP;
  614                         break;
  615                 }
  616                 xpt_release_bus(bus);
  617                 break;
  618         }
  619         /*
  620          * This is the getpassthru ioctl. It takes a XPT_GDEVLIST ccb as input,
  621          * with the periphal driver name and unit name filled in.  The other
  622          * fields don't really matter as input.  The passthrough driver name
  623          * ("pass"), and unit number are passed back in the ccb.  The current
  624          * device generation number, and the index into the device peripheral
  625          * driver list, and the status are also passed back.  Note that
  626          * since we do everything in one pass, unlike the XPT_GDEVLIST ccb,
  627          * we never return a status of CAM_GDEVLIST_LIST_CHANGED.  It is
  628          * (or rather should be) impossible for the device peripheral driver
  629          * list to change since we look at the whole thing in one pass, and
  630          * we do it with lock protection.
  631          *
  632          */
  633         case CAMGETPASSTHRU: {
  634                 union ccb *ccb;
  635                 struct cam_periph *periph;
  636                 struct periph_driver **p_drv;
  637                 char   *name;
  638                 u_int unit;
  639                 u_int cur_generation;
  640                 int base_periph_found;
  641                 int splbreaknum;
  642 
  643                 ccb = (union ccb *)addr;
  644                 unit = ccb->cgdl.unit_number;
  645                 name = ccb->cgdl.periph_name;
  646                 /*
  647                  * Every 100 devices, we want to drop our lock protection to
  648                  * give the software interrupt handler a chance to run.
  649                  * Most systems won't run into this check, but this should
  650                  * avoid starvation in the software interrupt handler in
  651                  * large systems.
  652                  */
  653                 splbreaknum = 100;
  654 
  655                 ccb = (union ccb *)addr;
  656 
  657                 base_periph_found = 0;
  658 
  659                 /*
  660                  * Sanity check -- make sure we don't get a null peripheral
  661                  * driver name.
  662                  */
  663                 if (*ccb->cgdl.periph_name == '\0') {
  664                         error = EINVAL;
  665                         break;
  666                 }
  667 
  668                 /* Keep the list from changing while we traverse it */
  669                 mtx_lock(&xsoftc.xpt_topo_lock);
  670 ptstartover:
  671                 cur_generation = xsoftc.xpt_generation;
  672 
  673                 /* first find our driver in the list of drivers */
  674                 for (p_drv = periph_drivers; *p_drv != NULL; p_drv++)
  675                         if (strcmp((*p_drv)->driver_name, name) == 0)
  676                                 break;
  677 
  678                 if (*p_drv == NULL) {
  679                         mtx_unlock(&xsoftc.xpt_topo_lock);
  680                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
  681                         ccb->cgdl.status = CAM_GDEVLIST_ERROR;
  682                         *ccb->cgdl.periph_name = '\0';
  683                         ccb->cgdl.unit_number = 0;
  684                         error = ENOENT;
  685                         break;
  686                 }
  687 
  688                 /*
  689                  * Run through every peripheral instance of this driver
  690                  * and check to see whether it matches the unit passed
  691                  * in by the user.  If it does, get out of the loops and
  692                  * find the passthrough driver associated with that
  693                  * peripheral driver.
  694                  */
  695                 for (periph = TAILQ_FIRST(&(*p_drv)->units); periph != NULL;
  696                      periph = TAILQ_NEXT(periph, unit_links)) {
  697 
  698                         if (periph->unit_number == unit) {
  699                                 break;
  700                         } else if (--splbreaknum == 0) {
  701                                 mtx_unlock(&xsoftc.xpt_topo_lock);
  702                                 mtx_lock(&xsoftc.xpt_topo_lock);
  703                                 splbreaknum = 100;
  704                                 if (cur_generation != xsoftc.xpt_generation)
  705                                        goto ptstartover;
  706                         }
  707                 }
  708                 /*
  709                  * If we found the peripheral driver that the user passed
  710                  * in, go through all of the peripheral drivers for that
  711                  * particular device and look for a passthrough driver.
  712                  */
  713                 if (periph != NULL) {
  714                         struct cam_ed *device;
  715                         int i;
  716 
  717                         base_periph_found = 1;
  718                         device = periph->path->device;
  719                         for (i = 0, periph = SLIST_FIRST(&device->periphs);
  720                              periph != NULL;
  721                              periph = SLIST_NEXT(periph, periph_links), i++) {
  722                                 /*
  723                                  * Check to see whether we have a
  724                                  * passthrough device or not.
  725                                  */
  726                                 if (strcmp(periph->periph_name, "pass") == 0) {
  727                                         /*
  728                                          * Fill in the getdevlist fields.
  729                                          */
  730                                         strcpy(ccb->cgdl.periph_name,
  731                                                periph->periph_name);
  732                                         ccb->cgdl.unit_number =
  733                                                 periph->unit_number;
  734                                         if (SLIST_NEXT(periph, periph_links))
  735                                                 ccb->cgdl.status =
  736                                                         CAM_GDEVLIST_MORE_DEVS;
  737                                         else
  738                                                 ccb->cgdl.status =
  739                                                        CAM_GDEVLIST_LAST_DEVICE;
  740                                         ccb->cgdl.generation =
  741                                                 device->generation;
  742                                         ccb->cgdl.index = i;
  743                                         /*
  744                                          * Fill in some CCB header fields
  745                                          * that the user may want.
  746                                          */
  747                                         ccb->ccb_h.path_id =
  748                                                 periph->path->bus->path_id;
  749                                         ccb->ccb_h.target_id =
  750                                                 periph->path->target->target_id;
  751                                         ccb->ccb_h.target_lun =
  752                                                 periph->path->device->lun_id;
  753                                         ccb->ccb_h.status = CAM_REQ_CMP;
  754                                         break;
  755                                 }
  756                         }
  757                 }
  758 
  759                 /*
  760                  * If the periph is null here, one of two things has
  761                  * happened.  The first possibility is that we couldn't
  762                  * find the unit number of the particular peripheral driver
  763                  * that the user is asking about.  e.g. the user asks for
  764                  * the passthrough driver for "da11".  We find the list of
  765                  * "da" peripherals all right, but there is no unit 11.
  766                  * The other possibility is that we went through the list
  767                  * of peripheral drivers attached to the device structure,
  768                  * but didn't find one with the name "pass".  Either way,
  769                  * we return ENOENT, since we couldn't find something.
  770                  */
  771                 if (periph == NULL) {
  772                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
  773                         ccb->cgdl.status = CAM_GDEVLIST_ERROR;
  774                         *ccb->cgdl.periph_name = '\0';
  775                         ccb->cgdl.unit_number = 0;
  776                         error = ENOENT;
  777                         /*
  778                          * It is unfortunate that this is even necessary,
  779                          * but there are many, many clueless users out there.
  780                          * If this is true, the user is looking for the
  781                          * passthrough driver, but doesn't have one in his
  782                          * kernel.
  783                          */
  784                         if (base_periph_found == 1) {
  785                                 printf("xptioctl: pass driver is not in the "
  786                                        "kernel\n");
  787                                 printf("xptioctl: put \"device pass\" in "
  788                                        "your kernel config file\n");
  789                         }
  790                 }
  791                 mtx_unlock(&xsoftc.xpt_topo_lock);
  792                 break;
  793                 }
  794         default:
  795                 error = ENOTTY;
  796                 break;
  797         }
  798 
  799         return(error);
  800 }
  801 
  802 static int
  803 cam_module_event_handler(module_t mod, int what, void *arg)
  804 {
  805         int error;
  806 
  807         switch (what) {
  808         case MOD_LOAD:
  809                 if ((error = xpt_init(NULL)) != 0)
  810                         return (error);
  811                 break;
  812         case MOD_UNLOAD:
  813                 return EBUSY;
  814         default:
  815                 return EOPNOTSUPP;
  816         }
  817 
  818         return 0;
  819 }
  820 
  821 /* thread to handle bus rescans */
  822 static void
  823 xpt_scanner_thread(void *dummy)
  824 {
  825         cam_isrq_t      queue;
  826         union ccb       *ccb;
  827         struct cam_sim  *sim;
  828 
  829         for (;;) {
  830                 /*
  831                  * Wait for a rescan request to come in.  When it does, splice
  832                  * it onto a queue from local storage so that the xpt lock
  833                  * doesn't need to be held while the requests are being
  834                  * processed.
  835                  */
  836                 xpt_lock_buses();
  837                 if (TAILQ_EMPTY(&xsoftc.ccb_scanq))
  838                         msleep(&xsoftc.ccb_scanq, &xsoftc.xpt_topo_lock, PRIBIO,
  839                                "ccb_scanq", 0);
  840                 TAILQ_INIT(&queue);
  841                 TAILQ_CONCAT(&queue, &xsoftc.ccb_scanq, sim_links.tqe);
  842                 xpt_unlock_buses();
  843 
  844                 while ((ccb = (union ccb *)TAILQ_FIRST(&queue)) != NULL) {
  845                         TAILQ_REMOVE(&queue, &ccb->ccb_h, sim_links.tqe);
  846 
  847                         sim = ccb->ccb_h.path->bus->sim;
  848                         CAM_SIM_LOCK(sim);
  849 
  850                         if( ccb->ccb_h.path->target->target_id == CAM_TARGET_WILDCARD )
  851                                 ccb->ccb_h.func_code = XPT_SCAN_BUS;
  852                         else
  853                                 ccb->ccb_h.func_code = XPT_SCAN_LUN;
  854                         ccb->ccb_h.cbfcnp = xptdone;
  855                         xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, CAM_PRIORITY_NORMAL);
  856                         cam_periph_runccb(ccb, NULL, 0, 0, NULL);
  857                         xpt_free_path(ccb->ccb_h.path);
  858                         xpt_free_ccb(ccb);
  859                         CAM_SIM_UNLOCK(sim);
  860                 }
  861         }
  862 }
  863 
  864 void
  865 xpt_rescan(union ccb *ccb)
  866 {
  867         struct ccb_hdr *hdr;
  868 
  869         /*
  870          * Don't make duplicate entries for the same paths.
  871          */
  872         xpt_lock_buses();
  873         TAILQ_FOREACH(hdr, &xsoftc.ccb_scanq, sim_links.tqe) {
  874                 if (xpt_path_comp(hdr->path, ccb->ccb_h.path) == 0) {
  875                         wakeup(&xsoftc.ccb_scanq);
  876                         xpt_unlock_buses();
  877                         xpt_print(ccb->ccb_h.path, "rescan already queued\n");
  878                         xpt_free_path(ccb->ccb_h.path);
  879                         xpt_free_ccb(ccb);
  880                         return;
  881                 }
  882         }
  883         TAILQ_INSERT_TAIL(&xsoftc.ccb_scanq, &ccb->ccb_h, sim_links.tqe);
  884         wakeup(&xsoftc.ccb_scanq);
  885         xpt_unlock_buses();
  886 }
  887 
  888 /* Functions accessed by the peripheral drivers */
  889 static int
  890 xpt_init(void *dummy)
  891 {
  892         struct cam_sim *xpt_sim;
  893         struct cam_path *path;
  894         struct cam_devq *devq;
  895         cam_status status;
  896 
  897         TAILQ_INIT(&xsoftc.xpt_busses);
  898         TAILQ_INIT(&cam_simq);
  899         TAILQ_INIT(&xsoftc.ccb_scanq);
  900         STAILQ_INIT(&xsoftc.highpowerq);
  901         xsoftc.num_highpower = CAM_MAX_HIGHPOWER;
  902 
  903         mtx_init(&cam_simq_lock, "CAM SIMQ lock", NULL, MTX_DEF);
  904         mtx_init(&xsoftc.xpt_lock, "XPT lock", NULL, MTX_DEF);
  905         mtx_init(&xsoftc.xpt_topo_lock, "XPT topology lock", NULL, MTX_DEF);
  906 
  907         /*
  908          * The xpt layer is, itself, the equivelent of a SIM.
  909          * Allow 16 ccbs in the ccb pool for it.  This should
  910          * give decent parallelism when we probe busses and
  911          * perform other XPT functions.
  912          */
  913         devq = cam_simq_alloc(16);
  914         xpt_sim = cam_sim_alloc(xptaction,
  915                                 xptpoll,
  916                                 "xpt",
  917                                 /*softc*/NULL,
  918                                 /*unit*/0,
  919                                 /*mtx*/&xsoftc.xpt_lock,
  920                                 /*max_dev_transactions*/0,
  921                                 /*max_tagged_dev_transactions*/0,
  922                                 devq);
  923         if (xpt_sim == NULL)
  924                 return (ENOMEM);
  925 
  926         xpt_sim->max_ccbs = 16;
  927 
  928         mtx_lock(&xsoftc.xpt_lock);
  929         if ((status = xpt_bus_register(xpt_sim, NULL, 0)) != CAM_SUCCESS) {
  930                 printf("xpt_init: xpt_bus_register failed with status %#x,"
  931                        " failing attach\n", status);
  932                 return (EINVAL);
  933         }
  934 
  935         /*
  936          * Looking at the XPT from the SIM layer, the XPT is
  937          * the equivelent of a peripheral driver.  Allocate
  938          * a peripheral driver entry for us.
  939          */
  940         if ((status = xpt_create_path(&path, NULL, CAM_XPT_PATH_ID,
  941                                       CAM_TARGET_WILDCARD,
  942                                       CAM_LUN_WILDCARD)) != CAM_REQ_CMP) {
  943                 printf("xpt_init: xpt_create_path failed with status %#x,"
  944                        " failing attach\n", status);
  945                 return (EINVAL);
  946         }
  947 
  948         cam_periph_alloc(xptregister, NULL, NULL, NULL, "xpt", CAM_PERIPH_BIO,
  949                          path, NULL, 0, xpt_sim);
  950         xpt_free_path(path);
  951         mtx_unlock(&xsoftc.xpt_lock);
  952 
  953         /*
  954          * Register a callback for when interrupts are enabled.
  955          */
  956         xsoftc.xpt_config_hook =
  957             (struct intr_config_hook *)malloc(sizeof(struct intr_config_hook),
  958                                               M_CAMXPT, M_NOWAIT | M_ZERO);
  959         if (xsoftc.xpt_config_hook == NULL) {
  960                 printf("xpt_init: Cannot malloc config hook "
  961                        "- failing attach\n");
  962                 return (ENOMEM);
  963         }
  964 
  965         xsoftc.xpt_config_hook->ich_func = xpt_config;
  966         if (config_intrhook_establish(xsoftc.xpt_config_hook) != 0) {
  967                 free (xsoftc.xpt_config_hook, M_CAMXPT);
  968                 printf("xpt_init: config_intrhook_establish failed "
  969                        "- failing attach\n");
  970         }
  971 
  972         /* fire up rescan thread */
  973         if (kproc_create(xpt_scanner_thread, NULL, NULL, 0, 0, "xpt_thrd")) {
  974                 printf("xpt_init: failed to create rescan thread\n");
  975         }
  976         /* Install our software interrupt handlers */
  977         swi_add(NULL, "cambio", camisr, NULL, SWI_CAMBIO, INTR_MPSAFE, &cambio_ih);
  978 
  979         return (0);
  980 }
  981 
  982 static cam_status
  983 xptregister(struct cam_periph *periph, void *arg)
  984 {
  985         struct cam_sim *xpt_sim;
  986 
  987         if (periph == NULL) {
  988                 printf("xptregister: periph was NULL!!\n");
  989                 return(CAM_REQ_CMP_ERR);
  990         }
  991 
  992         xpt_sim = (struct cam_sim *)arg;
  993         xpt_sim->softc = periph;
  994         xpt_periph = periph;
  995         periph->softc = NULL;
  996 
  997         return(CAM_REQ_CMP);
  998 }
  999 
 1000 int32_t
 1001 xpt_add_periph(struct cam_periph *periph)
 1002 {
 1003         struct cam_ed *device;
 1004         int32_t  status;
 1005         struct periph_list *periph_head;
 1006 
 1007         mtx_assert(periph->sim->mtx, MA_OWNED);
 1008 
 1009         device = periph->path->device;
 1010 
 1011         periph_head = &device->periphs;
 1012 
 1013         status = CAM_REQ_CMP;
 1014 
 1015         if (device != NULL) {
 1016                 /*
 1017                  * Make room for this peripheral
 1018                  * so it will fit in the queue
 1019                  * when it's scheduled to run
 1020                  */
 1021                 status = camq_resize(&device->drvq,
 1022                                      device->drvq.array_size + 1);
 1023 
 1024                 device->generation++;
 1025 
 1026                 SLIST_INSERT_HEAD(periph_head, periph, periph_links);
 1027         }
 1028 
 1029         mtx_lock(&xsoftc.xpt_topo_lock);
 1030         xsoftc.xpt_generation++;
 1031         mtx_unlock(&xsoftc.xpt_topo_lock);
 1032 
 1033         return (status);
 1034 }
 1035 
 1036 void
 1037 xpt_remove_periph(struct cam_periph *periph)
 1038 {
 1039         struct cam_ed *device;
 1040 
 1041         mtx_assert(periph->sim->mtx, MA_OWNED);
 1042 
 1043         device = periph->path->device;
 1044 
 1045         if (device != NULL) {
 1046                 struct periph_list *periph_head;
 1047 
 1048                 periph_head = &device->periphs;
 1049 
 1050                 /* Release the slot for this peripheral */
 1051                 camq_resize(&device->drvq, device->drvq.array_size - 1);
 1052 
 1053                 device->generation++;
 1054 
 1055                 SLIST_REMOVE(periph_head, periph, cam_periph, periph_links);
 1056         }
 1057 
 1058         mtx_lock(&xsoftc.xpt_topo_lock);
 1059         xsoftc.xpt_generation++;
 1060         mtx_unlock(&xsoftc.xpt_topo_lock);
 1061 }
 1062 
 1063 
 1064 void
 1065 xpt_announce_periph(struct cam_periph *periph, char *announce_string)
 1066 {
 1067         struct  ccb_pathinq cpi;
 1068         struct  ccb_trans_settings cts;
 1069         struct  cam_path *path;
 1070         u_int   speed;
 1071         u_int   freq;
 1072         u_int   mb;
 1073 
 1074         mtx_assert(periph->sim->mtx, MA_OWNED);
 1075 
 1076         path = periph->path;
 1077         /*
 1078          * To ensure that this is printed in one piece,
 1079          * mask out CAM interrupts.
 1080          */
 1081         printf("%s%d at %s%d bus %d scbus%d target %d lun %d\n",
 1082                periph->periph_name, periph->unit_number,
 1083                path->bus->sim->sim_name,
 1084                path->bus->sim->unit_number,
 1085                path->bus->sim->bus_id,
 1086                path->bus->path_id,
 1087                path->target->target_id,
 1088                path->device->lun_id);
 1089         printf("%s%d: ", periph->periph_name, periph->unit_number);
 1090         if (path->device->protocol == PROTO_SCSI)
 1091             scsi_print_inquiry(&path->device->inq_data);
 1092         else if (path->device->protocol == PROTO_ATA ||
 1093             path->device->protocol == PROTO_SATAPM)
 1094                 ata_print_ident(&path->device->ident_data);
 1095         else
 1096             printf("Unknown protocol device\n");
 1097         if (bootverbose && path->device->serial_num_len > 0) {
 1098                 /* Don't wrap the screen  - print only the first 60 chars */
 1099                 printf("%s%d: Serial Number %.60s\n", periph->periph_name,
 1100                        periph->unit_number, path->device->serial_num);
 1101         }
 1102         xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
 1103         cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 1104         cts.type = CTS_TYPE_CURRENT_SETTINGS;
 1105         xpt_action((union ccb*)&cts);
 1106         if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 1107                 return;
 1108         }
 1109 
 1110         /* Ask the SIM for its base transfer speed */
 1111         xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
 1112         cpi.ccb_h.func_code = XPT_PATH_INQ;
 1113         xpt_action((union ccb *)&cpi);
 1114 
 1115         speed = cpi.base_transfer_speed;
 1116         freq = 0;
 1117         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) {
 1118                 struct  ccb_trans_settings_spi *spi =
 1119                     &cts.xport_specific.spi;
 1120 
 1121                 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0
 1122                   && spi->sync_offset != 0) {
 1123                         freq = scsi_calc_syncsrate(spi->sync_period);
 1124                         speed = freq;
 1125                 }
 1126                 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
 1127                         speed *= (0x01 << spi->bus_width);
 1128         }
 1129         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) {
 1130                 struct  ccb_trans_settings_fc *fc =
 1131                     &cts.xport_specific.fc;
 1132 
 1133                 if (fc->valid & CTS_FC_VALID_SPEED)
 1134                         speed = fc->bitrate;
 1135         }
 1136         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SAS) {
 1137                 struct  ccb_trans_settings_sas *sas =
 1138                     &cts.xport_specific.sas;
 1139 
 1140                 if (sas->valid & CTS_SAS_VALID_SPEED)
 1141                         speed = sas->bitrate;
 1142         }
 1143         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
 1144                 struct  ccb_trans_settings_sata *sata =
 1145                     &cts.xport_specific.sata;
 1146 
 1147                 if (sata->valid & CTS_SATA_VALID_SPEED)
 1148                         speed = sata->bitrate;
 1149         }
 1150 
 1151         mb = speed / 1000;
 1152         if (mb > 0)
 1153                 printf("%s%d: %d.%03dMB/s transfers",
 1154                        periph->periph_name, periph->unit_number,
 1155                        mb, speed % 1000);
 1156         else
 1157                 printf("%s%d: %dKB/s transfers", periph->periph_name,
 1158                        periph->unit_number, speed);
 1159         /* Report additional information about SPI connections */
 1160         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) {
 1161                 struct  ccb_trans_settings_spi *spi;
 1162 
 1163                 spi = &cts.xport_specific.spi;
 1164                 if (freq != 0) {
 1165                         printf(" (%d.%03dMHz%s, offset %d", freq / 1000,
 1166                                freq % 1000,
 1167                                (spi->ppr_options & MSG_EXT_PPR_DT_REQ) != 0
 1168                              ? " DT" : "",
 1169                                spi->sync_offset);
 1170                 }
 1171                 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0
 1172                  && spi->bus_width > 0) {
 1173                         if (freq != 0) {
 1174                                 printf(", ");
 1175                         } else {
 1176                                 printf(" (");
 1177                         }
 1178                         printf("%dbit)", 8 * (0x01 << spi->bus_width));
 1179                 } else if (freq != 0) {
 1180                         printf(")");
 1181                 }
 1182         }
 1183         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) {
 1184                 struct  ccb_trans_settings_fc *fc;
 1185 
 1186                 fc = &cts.xport_specific.fc;
 1187                 if (fc->valid & CTS_FC_VALID_WWNN)
 1188                         printf(" WWNN 0x%llx", (long long) fc->wwnn);
 1189                 if (fc->valid & CTS_FC_VALID_WWPN)
 1190                         printf(" WWPN 0x%llx", (long long) fc->wwpn);
 1191                 if (fc->valid & CTS_FC_VALID_PORT)
 1192                         printf(" PortID 0x%x", fc->port);
 1193         }
 1194         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_ATA) {
 1195                 struct ccb_trans_settings_ata *ata =
 1196                     &cts.xport_specific.ata;
 1197 
 1198                 if (ata->valid & CTS_ATA_VALID_BYTECOUNT)
 1199                         printf(" (PIO size %dbytes)", ata->bytecount);
 1200         }
 1201         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SATA) {
 1202                 struct ccb_trans_settings_sata *sata =
 1203                     &cts.xport_specific.sata;
 1204 
 1205                 if (sata->valid & CTS_SATA_VALID_BYTECOUNT)
 1206                         printf(" (PIO size %dbytes)", sata->bytecount);
 1207         }
 1208         if (path->device->inq_flags & SID_CmdQue
 1209          || path->device->flags & CAM_DEV_TAG_AFTER_COUNT) {
 1210                 printf("\n%s%d: Command Queueing enabled",
 1211                        periph->periph_name, periph->unit_number);
 1212         }
 1213         printf("\n");
 1214 
 1215         /*
 1216          * We only want to print the caller's announce string if they've
 1217          * passed one in..
 1218          */
 1219         if (announce_string != NULL)
 1220                 printf("%s%d: %s\n", periph->periph_name,
 1221                        periph->unit_number, announce_string);
 1222 }
 1223 
 1224 static dev_match_ret
 1225 xptbusmatch(struct dev_match_pattern *patterns, u_int num_patterns,
 1226             struct cam_eb *bus)
 1227 {
 1228         dev_match_ret retval;
 1229         int i;
 1230 
 1231         retval = DM_RET_NONE;
 1232 
 1233         /*
 1234          * If we aren't given something to match against, that's an error.
 1235          */
 1236         if (bus == NULL)
 1237                 return(DM_RET_ERROR);
 1238 
 1239         /*
 1240          * If there are no match entries, then this bus matches no
 1241          * matter what.
 1242          */
 1243         if ((patterns == NULL) || (num_patterns == 0))
 1244                 return(DM_RET_DESCEND | DM_RET_COPY);
 1245 
 1246         for (i = 0; i < num_patterns; i++) {
 1247                 struct bus_match_pattern *cur_pattern;
 1248 
 1249                 /*
 1250                  * If the pattern in question isn't for a bus node, we
 1251                  * aren't interested.  However, we do indicate to the
 1252                  * calling routine that we should continue descending the
 1253                  * tree, since the user wants to match against lower-level
 1254                  * EDT elements.
 1255                  */
 1256                 if (patterns[i].type != DEV_MATCH_BUS) {
 1257                         if ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE)
 1258                                 retval |= DM_RET_DESCEND;
 1259                         continue;
 1260                 }
 1261 
 1262                 cur_pattern = &patterns[i].pattern.bus_pattern;
 1263 
 1264                 /*
 1265                  * If they want to match any bus node, we give them any
 1266                  * device node.
 1267                  */
 1268                 if (cur_pattern->flags == BUS_MATCH_ANY) {
 1269                         /* set the copy flag */
 1270                         retval |= DM_RET_COPY;
 1271 
 1272                         /*
 1273                          * If we've already decided on an action, go ahead
 1274                          * and return.
 1275                          */
 1276                         if ((retval & DM_RET_ACTION_MASK) != DM_RET_NONE)
 1277                                 return(retval);
 1278                 }
 1279 
 1280                 /*
 1281                  * Not sure why someone would do this...
 1282                  */
 1283                 if (cur_pattern->flags == BUS_MATCH_NONE)
 1284                         continue;
 1285 
 1286                 if (((cur_pattern->flags & BUS_MATCH_PATH) != 0)
 1287                  && (cur_pattern->path_id != bus->path_id))
 1288                         continue;
 1289 
 1290                 if (((cur_pattern->flags & BUS_MATCH_BUS_ID) != 0)
 1291                  && (cur_pattern->bus_id != bus->sim->bus_id))
 1292                         continue;
 1293 
 1294                 if (((cur_pattern->flags & BUS_MATCH_UNIT) != 0)
 1295                  && (cur_pattern->unit_number != bus->sim->unit_number))
 1296                         continue;
 1297 
 1298                 if (((cur_pattern->flags & BUS_MATCH_NAME) != 0)
 1299                  && (strncmp(cur_pattern->dev_name, bus->sim->sim_name,
 1300                              DEV_IDLEN) != 0))
 1301                         continue;
 1302 
 1303                 /*
 1304                  * If we get to this point, the user definitely wants
 1305                  * information on this bus.  So tell the caller to copy the
 1306                  * data out.
 1307                  */
 1308                 retval |= DM_RET_COPY;
 1309 
 1310                 /*
 1311                  * If the return action has been set to descend, then we
 1312                  * know that we've already seen a non-bus matching
 1313                  * expression, therefore we need to further descend the tree.
 1314                  * This won't change by continuing around the loop, so we
 1315                  * go ahead and return.  If we haven't seen a non-bus
 1316                  * matching expression, we keep going around the loop until
 1317                  * we exhaust the matching expressions.  We'll set the stop
 1318                  * flag once we fall out of the loop.
 1319                  */
 1320                 if ((retval & DM_RET_ACTION_MASK) == DM_RET_DESCEND)
 1321                         return(retval);
 1322         }
 1323 
 1324         /*
 1325          * If the return action hasn't been set to descend yet, that means
 1326          * we haven't seen anything other than bus matching patterns.  So
 1327          * tell the caller to stop descending the tree -- the user doesn't
 1328          * want to match against lower level tree elements.
 1329          */
 1330         if ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE)
 1331                 retval |= DM_RET_STOP;
 1332 
 1333         return(retval);
 1334 }
 1335 
 1336 static dev_match_ret
 1337 xptdevicematch(struct dev_match_pattern *patterns, u_int num_patterns,
 1338                struct cam_ed *device)
 1339 {
 1340         dev_match_ret retval;
 1341         int i;
 1342 
 1343         retval = DM_RET_NONE;
 1344 
 1345         /*
 1346          * If we aren't given something to match against, that's an error.
 1347          */
 1348         if (device == NULL)
 1349                 return(DM_RET_ERROR);
 1350 
 1351         /*
 1352          * If there are no match entries, then this device matches no
 1353          * matter what.
 1354          */
 1355         if ((patterns == NULL) || (num_patterns == 0))
 1356                 return(DM_RET_DESCEND | DM_RET_COPY);
 1357 
 1358         for (i = 0; i < num_patterns; i++) {
 1359                 struct device_match_pattern *cur_pattern;
 1360 
 1361                 /*
 1362                  * If the pattern in question isn't for a device node, we
 1363                  * aren't interested.
 1364                  */
 1365                 if (patterns[i].type != DEV_MATCH_DEVICE) {
 1366                         if ((patterns[i].type == DEV_MATCH_PERIPH)
 1367                          && ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE))
 1368                                 retval |= DM_RET_DESCEND;
 1369                         continue;
 1370                 }
 1371 
 1372                 cur_pattern = &patterns[i].pattern.device_pattern;
 1373 
 1374                 /*
 1375                  * If they want to match any device node, we give them any
 1376                  * device node.
 1377                  */
 1378                 if (cur_pattern->flags == DEV_MATCH_ANY) {
 1379                         /* set the copy flag */
 1380                         retval |= DM_RET_COPY;
 1381 
 1382 
 1383                         /*
 1384                          * If we've already decided on an action, go ahead
 1385                          * and return.
 1386                          */
 1387                         if ((retval & DM_RET_ACTION_MASK) != DM_RET_NONE)
 1388                                 return(retval);
 1389                 }
 1390 
 1391                 /*
 1392                  * Not sure why someone would do this...
 1393                  */
 1394                 if (cur_pattern->flags == DEV_MATCH_NONE)
 1395                         continue;
 1396 
 1397                 if (((cur_pattern->flags & DEV_MATCH_PATH) != 0)
 1398                  && (cur_pattern->path_id != device->target->bus->path_id))
 1399                         continue;
 1400 
 1401                 if (((cur_pattern->flags & DEV_MATCH_TARGET) != 0)
 1402                  && (cur_pattern->target_id != device->target->target_id))
 1403                         continue;
 1404 
 1405                 if (((cur_pattern->flags & DEV_MATCH_LUN) != 0)
 1406                  && (cur_pattern->target_lun != device->lun_id))
 1407                         continue;
 1408 
 1409                 if (((cur_pattern->flags & DEV_MATCH_INQUIRY) != 0)
 1410                  && (cam_quirkmatch((caddr_t)&device->inq_data,
 1411                                     (caddr_t)&cur_pattern->inq_pat,
 1412                                     1, sizeof(cur_pattern->inq_pat),
 1413                                     scsi_static_inquiry_match) == NULL))
 1414                         continue;
 1415 
 1416                 /*
 1417                  * If we get to this point, the user definitely wants
 1418                  * information on this device.  So tell the caller to copy
 1419                  * the data out.
 1420                  */
 1421                 retval |= DM_RET_COPY;
 1422 
 1423                 /*
 1424                  * If the return action has been set to descend, then we
 1425                  * know that we've already seen a peripheral matching
 1426                  * expression, therefore we need to further descend the tree.
 1427                  * This won't change by continuing around the loop, so we
 1428                  * go ahead and return.  If we haven't seen a peripheral
 1429                  * matching expression, we keep going around the loop until
 1430                  * we exhaust the matching expressions.  We'll set the stop
 1431                  * flag once we fall out of the loop.
 1432                  */
 1433                 if ((retval & DM_RET_ACTION_MASK) == DM_RET_DESCEND)
 1434                         return(retval);
 1435         }
 1436 
 1437         /*
 1438          * If the return action hasn't been set to descend yet, that means
 1439          * we haven't seen any peripheral matching patterns.  So tell the
 1440          * caller to stop descending the tree -- the user doesn't want to
 1441          * match against lower level tree elements.
 1442          */
 1443         if ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE)
 1444                 retval |= DM_RET_STOP;
 1445 
 1446         return(retval);
 1447 }
 1448 
 1449 /*
 1450  * Match a single peripheral against any number of match patterns.
 1451  */
 1452 static dev_match_ret
 1453 xptperiphmatch(struct dev_match_pattern *patterns, u_int num_patterns,
 1454                struct cam_periph *periph)
 1455 {
 1456         dev_match_ret retval;
 1457         int i;
 1458 
 1459         /*
 1460          * If we aren't given something to match against, that's an error.
 1461          */
 1462         if (periph == NULL)
 1463                 return(DM_RET_ERROR);
 1464 
 1465         /*
 1466          * If there are no match entries, then this peripheral matches no
 1467          * matter what.
 1468          */
 1469         if ((patterns == NULL) || (num_patterns == 0))
 1470                 return(DM_RET_STOP | DM_RET_COPY);
 1471 
 1472         /*
 1473          * There aren't any nodes below a peripheral node, so there's no
 1474          * reason to descend the tree any further.
 1475          */
 1476         retval = DM_RET_STOP;
 1477 
 1478         for (i = 0; i < num_patterns; i++) {
 1479                 struct periph_match_pattern *cur_pattern;
 1480 
 1481                 /*
 1482                  * If the pattern in question isn't for a peripheral, we
 1483                  * aren't interested.
 1484                  */
 1485                 if (patterns[i].type != DEV_MATCH_PERIPH)
 1486                         continue;
 1487 
 1488                 cur_pattern = &patterns[i].pattern.periph_pattern;
 1489 
 1490                 /*
 1491                  * If they want to match on anything, then we will do so.
 1492                  */
 1493                 if (cur_pattern->flags == PERIPH_MATCH_ANY) {
 1494                         /* set the copy flag */
 1495                         retval |= DM_RET_COPY;
 1496 
 1497                         /*
 1498                          * We've already set the return action to stop,
 1499                          * since there are no nodes below peripherals in
 1500                          * the tree.
 1501                          */
 1502                         return(retval);
 1503                 }
 1504 
 1505                 /*
 1506                  * Not sure why someone would do this...
 1507                  */
 1508                 if (cur_pattern->flags == PERIPH_MATCH_NONE)
 1509                         continue;
 1510 
 1511                 if (((cur_pattern->flags & PERIPH_MATCH_PATH) != 0)
 1512                  && (cur_pattern->path_id != periph->path->bus->path_id))
 1513                         continue;
 1514 
 1515                 /*
 1516                  * For the target and lun id's, we have to make sure the
 1517                  * target and lun pointers aren't NULL.  The xpt peripheral
 1518                  * has a wildcard target and device.
 1519                  */
 1520                 if (((cur_pattern->flags & PERIPH_MATCH_TARGET) != 0)
 1521                  && ((periph->path->target == NULL)
 1522                  ||(cur_pattern->target_id != periph->path->target->target_id)))
 1523                         continue;
 1524 
 1525                 if (((cur_pattern->flags & PERIPH_MATCH_LUN) != 0)
 1526                  && ((periph->path->device == NULL)
 1527                  || (cur_pattern->target_lun != periph->path->device->lun_id)))
 1528                         continue;
 1529 
 1530                 if (((cur_pattern->flags & PERIPH_MATCH_UNIT) != 0)
 1531                  && (cur_pattern->unit_number != periph->unit_number))
 1532                         continue;
 1533 
 1534                 if (((cur_pattern->flags & PERIPH_MATCH_NAME) != 0)
 1535                  && (strncmp(cur_pattern->periph_name, periph->periph_name,
 1536                              DEV_IDLEN) != 0))
 1537                         continue;
 1538 
 1539                 /*
 1540                  * If we get to this point, the user definitely wants
 1541                  * information on this peripheral.  So tell the caller to
 1542                  * copy the data out.
 1543                  */
 1544                 retval |= DM_RET_COPY;
 1545 
 1546                 /*
 1547                  * The return action has already been set to stop, since
 1548                  * peripherals don't have any nodes below them in the EDT.
 1549                  */
 1550                 return(retval);
 1551         }
 1552 
 1553         /*
 1554          * If we get to this point, the peripheral that was passed in
 1555          * doesn't match any of the patterns.
 1556          */
 1557         return(retval);
 1558 }
 1559 
 1560 static int
 1561 xptedtbusfunc(struct cam_eb *bus, void *arg)
 1562 {
 1563         struct ccb_dev_match *cdm;
 1564         dev_match_ret retval;
 1565 
 1566         cdm = (struct ccb_dev_match *)arg;
 1567 
 1568         /*
 1569          * If our position is for something deeper in the tree, that means
 1570          * that we've already seen this node.  So, we keep going down.
 1571          */
 1572         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 1573          && (cdm->pos.cookie.bus == bus)
 1574          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 1575          && (cdm->pos.cookie.target != NULL))
 1576                 retval = DM_RET_DESCEND;
 1577         else
 1578                 retval = xptbusmatch(cdm->patterns, cdm->num_patterns, bus);
 1579 
 1580         /*
 1581          * If we got an error, bail out of the search.
 1582          */
 1583         if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
 1584                 cdm->status = CAM_DEV_MATCH_ERROR;
 1585                 return(0);
 1586         }
 1587 
 1588         /*
 1589          * If the copy flag is set, copy this bus out.
 1590          */
 1591         if (retval & DM_RET_COPY) {
 1592                 int spaceleft, j;
 1593 
 1594                 spaceleft = cdm->match_buf_len - (cdm->num_matches *
 1595                         sizeof(struct dev_match_result));
 1596 
 1597                 /*
 1598                  * If we don't have enough space to put in another
 1599                  * match result, save our position and tell the
 1600                  * user there are more devices to check.
 1601                  */
 1602                 if (spaceleft < sizeof(struct dev_match_result)) {
 1603                         bzero(&cdm->pos, sizeof(cdm->pos));
 1604                         cdm->pos.position_type =
 1605                                 CAM_DEV_POS_EDT | CAM_DEV_POS_BUS;
 1606 
 1607                         cdm->pos.cookie.bus = bus;
 1608                         cdm->pos.generations[CAM_BUS_GENERATION]=
 1609                                 xsoftc.bus_generation;
 1610                         cdm->status = CAM_DEV_MATCH_MORE;
 1611                         return(0);
 1612                 }
 1613                 j = cdm->num_matches;
 1614                 cdm->num_matches++;
 1615                 cdm->matches[j].type = DEV_MATCH_BUS;
 1616                 cdm->matches[j].result.bus_result.path_id = bus->path_id;
 1617                 cdm->matches[j].result.bus_result.bus_id = bus->sim->bus_id;
 1618                 cdm->matches[j].result.bus_result.unit_number =
 1619                         bus->sim->unit_number;
 1620                 strncpy(cdm->matches[j].result.bus_result.dev_name,
 1621                         bus->sim->sim_name, DEV_IDLEN);
 1622         }
 1623 
 1624         /*
 1625          * If the user is only interested in busses, there's no
 1626          * reason to descend to the next level in the tree.
 1627          */
 1628         if ((retval & DM_RET_ACTION_MASK) == DM_RET_STOP)
 1629                 return(1);
 1630 
 1631         /*
 1632          * If there is a target generation recorded, check it to
 1633          * make sure the target list hasn't changed.
 1634          */
 1635         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 1636          && (bus == cdm->pos.cookie.bus)
 1637          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 1638          && (cdm->pos.generations[CAM_TARGET_GENERATION] != 0)
 1639          && (cdm->pos.generations[CAM_TARGET_GENERATION] !=
 1640              bus->generation)) {
 1641                 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
 1642                 return(0);
 1643         }
 1644 
 1645         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 1646          && (cdm->pos.cookie.bus == bus)
 1647          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 1648          && (cdm->pos.cookie.target != NULL))
 1649                 return(xpttargettraverse(bus,
 1650                                         (struct cam_et *)cdm->pos.cookie.target,
 1651                                          xptedttargetfunc, arg));
 1652         else
 1653                 return(xpttargettraverse(bus, NULL, xptedttargetfunc, arg));
 1654 }
 1655 
 1656 static int
 1657 xptedttargetfunc(struct cam_et *target, void *arg)
 1658 {
 1659         struct ccb_dev_match *cdm;
 1660 
 1661         cdm = (struct ccb_dev_match *)arg;
 1662 
 1663         /*
 1664          * If there is a device list generation recorded, check it to
 1665          * make sure the device list hasn't changed.
 1666          */
 1667         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 1668          && (cdm->pos.cookie.bus == target->bus)
 1669          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 1670          && (cdm->pos.cookie.target == target)
 1671          && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
 1672          && (cdm->pos.generations[CAM_DEV_GENERATION] != 0)
 1673          && (cdm->pos.generations[CAM_DEV_GENERATION] !=
 1674              target->generation)) {
 1675                 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
 1676                 return(0);
 1677         }
 1678 
 1679         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 1680          && (cdm->pos.cookie.bus == target->bus)
 1681          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 1682          && (cdm->pos.cookie.target == target)
 1683          && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
 1684          && (cdm->pos.cookie.device != NULL))
 1685                 return(xptdevicetraverse(target,
 1686                                         (struct cam_ed *)cdm->pos.cookie.device,
 1687                                          xptedtdevicefunc, arg));
 1688         else
 1689                 return(xptdevicetraverse(target, NULL, xptedtdevicefunc, arg));
 1690 }
 1691 
 1692 static int
 1693 xptedtdevicefunc(struct cam_ed *device, void *arg)
 1694 {
 1695 
 1696         struct ccb_dev_match *cdm;
 1697         dev_match_ret retval;
 1698 
 1699         cdm = (struct ccb_dev_match *)arg;
 1700 
 1701         /*
 1702          * If our position is for something deeper in the tree, that means
 1703          * that we've already seen this node.  So, we keep going down.
 1704          */
 1705         if ((cdm->pos.position_type & CAM_DEV_POS_DEVICE)
 1706          && (cdm->pos.cookie.device == device)
 1707          && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
 1708          && (cdm->pos.cookie.periph != NULL))
 1709                 retval = DM_RET_DESCEND;
 1710         else
 1711                 retval = xptdevicematch(cdm->patterns, cdm->num_patterns,
 1712                                         device);
 1713 
 1714         if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
 1715                 cdm->status = CAM_DEV_MATCH_ERROR;
 1716                 return(0);
 1717         }
 1718 
 1719         /*
 1720          * If the copy flag is set, copy this device out.
 1721          */
 1722         if (retval & DM_RET_COPY) {
 1723                 int spaceleft, j;
 1724 
 1725                 spaceleft = cdm->match_buf_len - (cdm->num_matches *
 1726                         sizeof(struct dev_match_result));
 1727 
 1728                 /*
 1729                  * If we don't have enough space to put in another
 1730                  * match result, save our position and tell the
 1731                  * user there are more devices to check.
 1732                  */
 1733                 if (spaceleft < sizeof(struct dev_match_result)) {
 1734                         bzero(&cdm->pos, sizeof(cdm->pos));
 1735                         cdm->pos.position_type =
 1736                                 CAM_DEV_POS_EDT | CAM_DEV_POS_BUS |
 1737                                 CAM_DEV_POS_TARGET | CAM_DEV_POS_DEVICE;
 1738 
 1739                         cdm->pos.cookie.bus = device->target->bus;
 1740                         cdm->pos.generations[CAM_BUS_GENERATION]=
 1741                                 xsoftc.bus_generation;
 1742                         cdm->pos.cookie.target = device->target;
 1743                         cdm->pos.generations[CAM_TARGET_GENERATION] =
 1744                                 device->target->bus->generation;
 1745                         cdm->pos.cookie.device = device;
 1746                         cdm->pos.generations[CAM_DEV_GENERATION] =
 1747                                 device->target->generation;
 1748                         cdm->status = CAM_DEV_MATCH_MORE;
 1749                         return(0);
 1750                 }
 1751                 j = cdm->num_matches;
 1752                 cdm->num_matches++;
 1753                 cdm->matches[j].type = DEV_MATCH_DEVICE;
 1754                 cdm->matches[j].result.device_result.path_id =
 1755                         device->target->bus->path_id;
 1756                 cdm->matches[j].result.device_result.target_id =
 1757                         device->target->target_id;
 1758                 cdm->matches[j].result.device_result.target_lun =
 1759                         device->lun_id;
 1760                 cdm->matches[j].result.device_result.protocol =
 1761                         device->protocol;
 1762                 bcopy(&device->inq_data,
 1763                       &cdm->matches[j].result.device_result.inq_data,
 1764                       sizeof(struct scsi_inquiry_data));
 1765                 bcopy(&device->ident_data,
 1766                       &cdm->matches[j].result.device_result.ident_data,
 1767                       sizeof(struct ata_params));
 1768 
 1769                 /* Let the user know whether this device is unconfigured */
 1770                 if (device->flags & CAM_DEV_UNCONFIGURED)
 1771                         cdm->matches[j].result.device_result.flags =
 1772                                 DEV_RESULT_UNCONFIGURED;
 1773                 else
 1774                         cdm->matches[j].result.device_result.flags =
 1775                                 DEV_RESULT_NOFLAG;
 1776         }
 1777 
 1778         /*
 1779          * If the user isn't interested in peripherals, don't descend
 1780          * the tree any further.
 1781          */
 1782         if ((retval & DM_RET_ACTION_MASK) == DM_RET_STOP)
 1783                 return(1);
 1784 
 1785         /*
 1786          * If there is a peripheral list generation recorded, make sure
 1787          * it hasn't changed.
 1788          */
 1789         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 1790          && (device->target->bus == cdm->pos.cookie.bus)
 1791          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 1792          && (device->target == cdm->pos.cookie.target)
 1793          && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
 1794          && (device == cdm->pos.cookie.device)
 1795          && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
 1796          && (cdm->pos.generations[CAM_PERIPH_GENERATION] != 0)
 1797          && (cdm->pos.generations[CAM_PERIPH_GENERATION] !=
 1798              device->generation)){
 1799                 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
 1800                 return(0);
 1801         }
 1802 
 1803         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 1804          && (cdm->pos.cookie.bus == device->target->bus)
 1805          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 1806          && (cdm->pos.cookie.target == device->target)
 1807          && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
 1808          && (cdm->pos.cookie.device == device)
 1809          && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
 1810          && (cdm->pos.cookie.periph != NULL))
 1811                 return(xptperiphtraverse(device,
 1812                                 (struct cam_periph *)cdm->pos.cookie.periph,
 1813                                 xptedtperiphfunc, arg));
 1814         else
 1815                 return(xptperiphtraverse(device, NULL, xptedtperiphfunc, arg));
 1816 }
 1817 
 1818 static int
 1819 xptedtperiphfunc(struct cam_periph *periph, void *arg)
 1820 {
 1821         struct ccb_dev_match *cdm;
 1822         dev_match_ret retval;
 1823 
 1824         cdm = (struct ccb_dev_match *)arg;
 1825 
 1826         retval = xptperiphmatch(cdm->patterns, cdm->num_patterns, periph);
 1827 
 1828         if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
 1829                 cdm->status = CAM_DEV_MATCH_ERROR;
 1830                 return(0);
 1831         }
 1832 
 1833         /*
 1834          * If the copy flag is set, copy this peripheral out.
 1835          */
 1836         if (retval & DM_RET_COPY) {
 1837                 int spaceleft, j;
 1838 
 1839                 spaceleft = cdm->match_buf_len - (cdm->num_matches *
 1840                         sizeof(struct dev_match_result));
 1841 
 1842                 /*
 1843                  * If we don't have enough space to put in another
 1844                  * match result, save our position and tell the
 1845                  * user there are more devices to check.
 1846                  */
 1847                 if (spaceleft < sizeof(struct dev_match_result)) {
 1848                         bzero(&cdm->pos, sizeof(cdm->pos));
 1849                         cdm->pos.position_type =
 1850                                 CAM_DEV_POS_EDT | CAM_DEV_POS_BUS |
 1851                                 CAM_DEV_POS_TARGET | CAM_DEV_POS_DEVICE |
 1852                                 CAM_DEV_POS_PERIPH;
 1853 
 1854                         cdm->pos.cookie.bus = periph->path->bus;
 1855                         cdm->pos.generations[CAM_BUS_GENERATION]=
 1856                                 xsoftc.bus_generation;
 1857                         cdm->pos.cookie.target = periph->path->target;
 1858                         cdm->pos.generations[CAM_TARGET_GENERATION] =
 1859                                 periph->path->bus->generation;
 1860                         cdm->pos.cookie.device = periph->path->device;
 1861                         cdm->pos.generations[CAM_DEV_GENERATION] =
 1862                                 periph->path->target->generation;
 1863                         cdm->pos.cookie.periph = periph;
 1864                         cdm->pos.generations[CAM_PERIPH_GENERATION] =
 1865                                 periph->path->device->generation;
 1866                         cdm->status = CAM_DEV_MATCH_MORE;
 1867                         return(0);
 1868                 }
 1869 
 1870                 j = cdm->num_matches;
 1871                 cdm->num_matches++;
 1872                 cdm->matches[j].type = DEV_MATCH_PERIPH;
 1873                 cdm->matches[j].result.periph_result.path_id =
 1874                         periph->path->bus->path_id;
 1875                 cdm->matches[j].result.periph_result.target_id =
 1876                         periph->path->target->target_id;
 1877                 cdm->matches[j].result.periph_result.target_lun =
 1878                         periph->path->device->lun_id;
 1879                 cdm->matches[j].result.periph_result.unit_number =
 1880                         periph->unit_number;
 1881                 strncpy(cdm->matches[j].result.periph_result.periph_name,
 1882                         periph->periph_name, DEV_IDLEN);
 1883         }
 1884 
 1885         return(1);
 1886 }
 1887 
 1888 static int
 1889 xptedtmatch(struct ccb_dev_match *cdm)
 1890 {
 1891         int ret;
 1892 
 1893         cdm->num_matches = 0;
 1894 
 1895         /*
 1896          * Check the bus list generation.  If it has changed, the user
 1897          * needs to reset everything and start over.
 1898          */
 1899         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 1900          && (cdm->pos.generations[CAM_BUS_GENERATION] != 0)
 1901          && (cdm->pos.generations[CAM_BUS_GENERATION] != xsoftc.bus_generation)) {
 1902                 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
 1903                 return(0);
 1904         }
 1905 
 1906         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 1907          && (cdm->pos.cookie.bus != NULL))
 1908                 ret = xptbustraverse((struct cam_eb *)cdm->pos.cookie.bus,
 1909                                      xptedtbusfunc, cdm);
 1910         else
 1911                 ret = xptbustraverse(NULL, xptedtbusfunc, cdm);
 1912 
 1913         /*
 1914          * If we get back 0, that means that we had to stop before fully
 1915          * traversing the EDT.  It also means that one of the subroutines
 1916          * has set the status field to the proper value.  If we get back 1,
 1917          * we've fully traversed the EDT and copied out any matching entries.
 1918          */
 1919         if (ret == 1)
 1920                 cdm->status = CAM_DEV_MATCH_LAST;
 1921 
 1922         return(ret);
 1923 }
 1924 
 1925 static int
 1926 xptplistpdrvfunc(struct periph_driver **pdrv, void *arg)
 1927 {
 1928         struct ccb_dev_match *cdm;
 1929 
 1930         cdm = (struct ccb_dev_match *)arg;
 1931 
 1932         if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
 1933          && (cdm->pos.cookie.pdrv == pdrv)
 1934          && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
 1935          && (cdm->pos.generations[CAM_PERIPH_GENERATION] != 0)
 1936          && (cdm->pos.generations[CAM_PERIPH_GENERATION] !=
 1937              (*pdrv)->generation)) {
 1938                 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
 1939                 return(0);
 1940         }
 1941 
 1942         if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
 1943          && (cdm->pos.cookie.pdrv == pdrv)
 1944          && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
 1945          && (cdm->pos.cookie.periph != NULL))
 1946                 return(xptpdperiphtraverse(pdrv,
 1947                                 (struct cam_periph *)cdm->pos.cookie.periph,
 1948                                 xptplistperiphfunc, arg));
 1949         else
 1950                 return(xptpdperiphtraverse(pdrv, NULL,xptplistperiphfunc, arg));
 1951 }
 1952 
 1953 static int
 1954 xptplistperiphfunc(struct cam_periph *periph, void *arg)
 1955 {
 1956         struct ccb_dev_match *cdm;
 1957         dev_match_ret retval;
 1958 
 1959         cdm = (struct ccb_dev_match *)arg;
 1960 
 1961         retval = xptperiphmatch(cdm->patterns, cdm->num_patterns, periph);
 1962 
 1963         if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
 1964                 cdm->status = CAM_DEV_MATCH_ERROR;
 1965                 return(0);
 1966         }
 1967 
 1968         /*
 1969          * If the copy flag is set, copy this peripheral out.
 1970          */
 1971         if (retval & DM_RET_COPY) {
 1972                 int spaceleft, j;
 1973 
 1974                 spaceleft = cdm->match_buf_len - (cdm->num_matches *
 1975                         sizeof(struct dev_match_result));
 1976 
 1977                 /*
 1978                  * If we don't have enough space to put in another
 1979                  * match result, save our position and tell the
 1980                  * user there are more devices to check.
 1981                  */
 1982                 if (spaceleft < sizeof(struct dev_match_result)) {
 1983                         struct periph_driver **pdrv;
 1984 
 1985                         pdrv = NULL;
 1986                         bzero(&cdm->pos, sizeof(cdm->pos));
 1987                         cdm->pos.position_type =
 1988                                 CAM_DEV_POS_PDRV | CAM_DEV_POS_PDPTR |
 1989                                 CAM_DEV_POS_PERIPH;
 1990 
 1991                         /*
 1992                          * This may look a bit non-sensical, but it is
 1993                          * actually quite logical.  There are very few
 1994                          * peripheral drivers, and bloating every peripheral
 1995                          * structure with a pointer back to its parent
 1996                          * peripheral driver linker set entry would cost
 1997                          * more in the long run than doing this quick lookup.
 1998                          */
 1999                         for (pdrv = periph_drivers; *pdrv != NULL; pdrv++) {
 2000                                 if (strcmp((*pdrv)->driver_name,
 2001                                     periph->periph_name) == 0)
 2002                                         break;
 2003                         }
 2004 
 2005                         if (*pdrv == NULL) {
 2006                                 cdm->status = CAM_DEV_MATCH_ERROR;
 2007                                 return(0);
 2008                         }
 2009 
 2010                         cdm->pos.cookie.pdrv = pdrv;
 2011                         /*
 2012                          * The periph generation slot does double duty, as
 2013                          * does the periph pointer slot.  They are used for
 2014                          * both edt and pdrv lookups and positioning.
 2015                          */
 2016                         cdm->pos.cookie.periph = periph;
 2017                         cdm->pos.generations[CAM_PERIPH_GENERATION] =
 2018                                 (*pdrv)->generation;
 2019                         cdm->status = CAM_DEV_MATCH_MORE;
 2020                         return(0);
 2021                 }
 2022 
 2023                 j = cdm->num_matches;
 2024                 cdm->num_matches++;
 2025                 cdm->matches[j].type = DEV_MATCH_PERIPH;
 2026                 cdm->matches[j].result.periph_result.path_id =
 2027                         periph->path->bus->path_id;
 2028 
 2029                 /*
 2030                  * The transport layer peripheral doesn't have a target or
 2031                  * lun.
 2032                  */
 2033                 if (periph->path->target)
 2034                         cdm->matches[j].result.periph_result.target_id =
 2035                                 periph->path->target->target_id;
 2036                 else
 2037                         cdm->matches[j].result.periph_result.target_id = -1;
 2038 
 2039                 if (periph->path->device)
 2040                         cdm->matches[j].result.periph_result.target_lun =
 2041                                 periph->path->device->lun_id;
 2042                 else
 2043                         cdm->matches[j].result.periph_result.target_lun = -1;
 2044 
 2045                 cdm->matches[j].result.periph_result.unit_number =
 2046                         periph->unit_number;
 2047                 strncpy(cdm->matches[j].result.periph_result.periph_name,
 2048                         periph->periph_name, DEV_IDLEN);
 2049         }
 2050 
 2051         return(1);
 2052 }
 2053 
 2054 static int
 2055 xptperiphlistmatch(struct ccb_dev_match *cdm)
 2056 {
 2057         int ret;
 2058 
 2059         cdm->num_matches = 0;
 2060 
 2061         /*
 2062          * At this point in the edt traversal function, we check the bus
 2063          * list generation to make sure that no busses have been added or
 2064          * removed since the user last sent a XPT_DEV_MATCH ccb through.
 2065          * For the peripheral driver list traversal function, however, we
 2066          * don't have to worry about new peripheral driver types coming or
 2067          * going; they're in a linker set, and therefore can't change
 2068          * without a recompile.
 2069          */
 2070 
 2071         if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
 2072          && (cdm->pos.cookie.pdrv != NULL))
 2073                 ret = xptpdrvtraverse(
 2074                                 (struct periph_driver **)cdm->pos.cookie.pdrv,
 2075                                 xptplistpdrvfunc, cdm);
 2076         else
 2077                 ret = xptpdrvtraverse(NULL, xptplistpdrvfunc, cdm);
 2078 
 2079         /*
 2080          * If we get back 0, that means that we had to stop before fully
 2081          * traversing the peripheral driver tree.  It also means that one of
 2082          * the subroutines has set the status field to the proper value.  If
 2083          * we get back 1, we've fully traversed the EDT and copied out any
 2084          * matching entries.
 2085          */
 2086         if (ret == 1)
 2087                 cdm->status = CAM_DEV_MATCH_LAST;
 2088 
 2089         return(ret);
 2090 }
 2091 
 2092 static int
 2093 xptbustraverse(struct cam_eb *start_bus, xpt_busfunc_t *tr_func, void *arg)
 2094 {
 2095         struct cam_eb *bus, *next_bus;
 2096         int retval;
 2097 
 2098         retval = 1;
 2099 
 2100         mtx_lock(&xsoftc.xpt_topo_lock);
 2101         for (bus = (start_bus ? start_bus : TAILQ_FIRST(&xsoftc.xpt_busses));
 2102              bus != NULL;
 2103              bus = next_bus) {
 2104                 next_bus = TAILQ_NEXT(bus, links);
 2105 
 2106                 mtx_unlock(&xsoftc.xpt_topo_lock);
 2107                 CAM_SIM_LOCK(bus->sim);
 2108                 retval = tr_func(bus, arg);
 2109                 CAM_SIM_UNLOCK(bus->sim);
 2110                 if (retval == 0)
 2111                         return(retval);
 2112                 mtx_lock(&xsoftc.xpt_topo_lock);
 2113         }
 2114         mtx_unlock(&xsoftc.xpt_topo_lock);
 2115 
 2116         return(retval);
 2117 }
 2118 
 2119 int
 2120 xpt_sim_opened(struct cam_sim *sim)
 2121 {
 2122         struct cam_eb *bus;
 2123         struct cam_et *target;
 2124         struct cam_ed *device;
 2125         struct cam_periph *periph;
 2126 
 2127         KASSERT(sim->refcount >= 1, ("sim->refcount >= 1"));
 2128         mtx_assert(sim->mtx, MA_OWNED);
 2129 
 2130         mtx_lock(&xsoftc.xpt_topo_lock);
 2131         TAILQ_FOREACH(bus, &xsoftc.xpt_busses, links) {
 2132                 if (bus->sim != sim)
 2133                         continue;
 2134 
 2135                 TAILQ_FOREACH(target, &bus->et_entries, links) {
 2136                         TAILQ_FOREACH(device, &target->ed_entries, links) {
 2137                                 SLIST_FOREACH(periph, &device->periphs,
 2138                                     periph_links) {
 2139                                         if (periph->refcount > 0) {
 2140                                                 mtx_unlock(&xsoftc.xpt_topo_lock);
 2141                                                 return (1);
 2142                                         }
 2143                                 }
 2144                         }
 2145                 }
 2146         }
 2147 
 2148         mtx_unlock(&xsoftc.xpt_topo_lock);
 2149         return (0);
 2150 }
 2151 
 2152 static int
 2153 xpttargettraverse(struct cam_eb *bus, struct cam_et *start_target,
 2154                   xpt_targetfunc_t *tr_func, void *arg)
 2155 {
 2156         struct cam_et *target, *next_target;
 2157         int retval;
 2158 
 2159         retval = 1;
 2160         for (target = (start_target ? start_target :
 2161                        TAILQ_FIRST(&bus->et_entries));
 2162              target != NULL; target = next_target) {
 2163 
 2164                 next_target = TAILQ_NEXT(target, links);
 2165 
 2166                 retval = tr_func(target, arg);
 2167 
 2168                 if (retval == 0)
 2169                         return(retval);
 2170         }
 2171 
 2172         return(retval);
 2173 }
 2174 
 2175 static int
 2176 xptdevicetraverse(struct cam_et *target, struct cam_ed *start_device,
 2177                   xpt_devicefunc_t *tr_func, void *arg)
 2178 {
 2179         struct cam_ed *device, *next_device;
 2180         int retval;
 2181 
 2182         retval = 1;
 2183         for (device = (start_device ? start_device :
 2184                        TAILQ_FIRST(&target->ed_entries));
 2185              device != NULL;
 2186              device = next_device) {
 2187 
 2188                 next_device = TAILQ_NEXT(device, links);
 2189 
 2190                 retval = tr_func(device, arg);
 2191 
 2192                 if (retval == 0)
 2193                         return(retval);
 2194         }
 2195 
 2196         return(retval);
 2197 }
 2198 
 2199 static int
 2200 xptperiphtraverse(struct cam_ed *device, struct cam_periph *start_periph,
 2201                   xpt_periphfunc_t *tr_func, void *arg)
 2202 {
 2203         struct cam_periph *periph, *next_periph;
 2204         int retval;
 2205 
 2206         retval = 1;
 2207 
 2208         for (periph = (start_periph ? start_periph :
 2209                        SLIST_FIRST(&device->periphs));
 2210              periph != NULL;
 2211              periph = next_periph) {
 2212 
 2213                 next_periph = SLIST_NEXT(periph, periph_links);
 2214 
 2215                 retval = tr_func(periph, arg);
 2216                 if (retval == 0)
 2217                         return(retval);
 2218         }
 2219 
 2220         return(retval);
 2221 }
 2222 
 2223 static int
 2224 xptpdrvtraverse(struct periph_driver **start_pdrv,
 2225                 xpt_pdrvfunc_t *tr_func, void *arg)
 2226 {
 2227         struct periph_driver **pdrv;
 2228         int retval;
 2229 
 2230         retval = 1;
 2231 
 2232         /*
 2233          * We don't traverse the peripheral driver list like we do the
 2234          * other lists, because it is a linker set, and therefore cannot be
 2235          * changed during runtime.  If the peripheral driver list is ever
 2236          * re-done to be something other than a linker set (i.e. it can
 2237          * change while the system is running), the list traversal should
 2238          * be modified to work like the other traversal functions.
 2239          */
 2240         for (pdrv = (start_pdrv ? start_pdrv : periph_drivers);
 2241              *pdrv != NULL; pdrv++) {
 2242                 retval = tr_func(pdrv, arg);
 2243 
 2244                 if (retval == 0)
 2245                         return(retval);
 2246         }
 2247 
 2248         return(retval);
 2249 }
 2250 
 2251 static int
 2252 xptpdperiphtraverse(struct periph_driver **pdrv,
 2253                     struct cam_periph *start_periph,
 2254                     xpt_periphfunc_t *tr_func, void *arg)
 2255 {
 2256         struct cam_periph *periph, *next_periph;
 2257         int retval;
 2258 
 2259         retval = 1;
 2260 
 2261         for (periph = (start_periph ? start_periph :
 2262              TAILQ_FIRST(&(*pdrv)->units)); periph != NULL;
 2263              periph = next_periph) {
 2264 
 2265                 next_periph = TAILQ_NEXT(periph, unit_links);
 2266 
 2267                 retval = tr_func(periph, arg);
 2268                 if (retval == 0)
 2269                         return(retval);
 2270         }
 2271         return(retval);
 2272 }
 2273 
 2274 static int
 2275 xptdefbusfunc(struct cam_eb *bus, void *arg)
 2276 {
 2277         struct xpt_traverse_config *tr_config;
 2278 
 2279         tr_config = (struct xpt_traverse_config *)arg;
 2280 
 2281         if (tr_config->depth == XPT_DEPTH_BUS) {
 2282                 xpt_busfunc_t *tr_func;
 2283 
 2284                 tr_func = (xpt_busfunc_t *)tr_config->tr_func;
 2285 
 2286                 return(tr_func(bus, tr_config->tr_arg));
 2287         } else
 2288                 return(xpttargettraverse(bus, NULL, xptdeftargetfunc, arg));
 2289 }
 2290 
 2291 static int
 2292 xptdeftargetfunc(struct cam_et *target, void *arg)
 2293 {
 2294         struct xpt_traverse_config *tr_config;
 2295 
 2296         tr_config = (struct xpt_traverse_config *)arg;
 2297 
 2298         if (tr_config->depth == XPT_DEPTH_TARGET) {
 2299                 xpt_targetfunc_t *tr_func;
 2300 
 2301                 tr_func = (xpt_targetfunc_t *)tr_config->tr_func;
 2302 
 2303                 return(tr_func(target, tr_config->tr_arg));
 2304         } else
 2305                 return(xptdevicetraverse(target, NULL, xptdefdevicefunc, arg));
 2306 }
 2307 
 2308 static int
 2309 xptdefdevicefunc(struct cam_ed *device, void *arg)
 2310 {
 2311         struct xpt_traverse_config *tr_config;
 2312 
 2313         tr_config = (struct xpt_traverse_config *)arg;
 2314 
 2315         if (tr_config->depth == XPT_DEPTH_DEVICE) {
 2316                 xpt_devicefunc_t *tr_func;
 2317 
 2318                 tr_func = (xpt_devicefunc_t *)tr_config->tr_func;
 2319 
 2320                 return(tr_func(device, tr_config->tr_arg));
 2321         } else
 2322                 return(xptperiphtraverse(device, NULL, xptdefperiphfunc, arg));
 2323 }
 2324 
 2325 static int
 2326 xptdefperiphfunc(struct cam_periph *periph, void *arg)
 2327 {
 2328         struct xpt_traverse_config *tr_config;
 2329         xpt_periphfunc_t *tr_func;
 2330 
 2331         tr_config = (struct xpt_traverse_config *)arg;
 2332 
 2333         tr_func = (xpt_periphfunc_t *)tr_config->tr_func;
 2334 
 2335         /*
 2336          * Unlike the other default functions, we don't check for depth
 2337          * here.  The peripheral driver level is the last level in the EDT,
 2338          * so if we're here, we should execute the function in question.
 2339          */
 2340         return(tr_func(periph, tr_config->tr_arg));
 2341 }
 2342 
 2343 /*
 2344  * Execute the given function for every bus in the EDT.
 2345  */
 2346 static int
 2347 xpt_for_all_busses(xpt_busfunc_t *tr_func, void *arg)
 2348 {
 2349         struct xpt_traverse_config tr_config;
 2350 
 2351         tr_config.depth = XPT_DEPTH_BUS;
 2352         tr_config.tr_func = tr_func;
 2353         tr_config.tr_arg = arg;
 2354 
 2355         return(xptbustraverse(NULL, xptdefbusfunc, &tr_config));
 2356 }
 2357 
 2358 /*
 2359  * Execute the given function for every device in the EDT.
 2360  */
 2361 static int
 2362 xpt_for_all_devices(xpt_devicefunc_t *tr_func, void *arg)
 2363 {
 2364         struct xpt_traverse_config tr_config;
 2365 
 2366         tr_config.depth = XPT_DEPTH_DEVICE;
 2367         tr_config.tr_func = tr_func;
 2368         tr_config.tr_arg = arg;
 2369 
 2370         return(xptbustraverse(NULL, xptdefbusfunc, &tr_config));
 2371 }
 2372 
 2373 static int
 2374 xptsetasyncfunc(struct cam_ed *device, void *arg)
 2375 {
 2376         struct cam_path path;
 2377         struct ccb_getdev cgd;
 2378         struct async_node *cur_entry;
 2379 
 2380         cur_entry = (struct async_node *)arg;
 2381 
 2382         /*
 2383          * Don't report unconfigured devices (Wildcard devs,
 2384          * devices only for target mode, device instances
 2385          * that have been invalidated but are waiting for
 2386          * their last reference count to be released).
 2387          */
 2388         if ((device->flags & CAM_DEV_UNCONFIGURED) != 0)
 2389                 return (1);
 2390 
 2391         xpt_compile_path(&path,
 2392                          NULL,
 2393                          device->target->bus->path_id,
 2394                          device->target->target_id,
 2395                          device->lun_id);
 2396         xpt_setup_ccb(&cgd.ccb_h, &path, CAM_PRIORITY_NORMAL);
 2397         cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 2398         xpt_action((union ccb *)&cgd);
 2399         cur_entry->callback(cur_entry->callback_arg,
 2400                             AC_FOUND_DEVICE,
 2401                             &path, &cgd);
 2402         xpt_release_path(&path);
 2403 
 2404         return(1);
 2405 }
 2406 
 2407 static int
 2408 xptsetasyncbusfunc(struct cam_eb *bus, void *arg)
 2409 {
 2410         struct cam_path path;
 2411         struct ccb_pathinq cpi;
 2412         struct async_node *cur_entry;
 2413 
 2414         cur_entry = (struct async_node *)arg;
 2415 
 2416         xpt_compile_path(&path, /*periph*/NULL,
 2417                          bus->sim->path_id,
 2418                          CAM_TARGET_WILDCARD,
 2419                          CAM_LUN_WILDCARD);
 2420         xpt_setup_ccb(&cpi.ccb_h, &path, CAM_PRIORITY_NORMAL);
 2421         cpi.ccb_h.func_code = XPT_PATH_INQ;
 2422         xpt_action((union ccb *)&cpi);
 2423         cur_entry->callback(cur_entry->callback_arg,
 2424                             AC_PATH_REGISTERED,
 2425                             &path, &cpi);
 2426         xpt_release_path(&path);
 2427 
 2428         return(1);
 2429 }
 2430 
 2431 static void
 2432 xpt_action_sasync_cb(void *context, int pending)
 2433 {
 2434         struct async_node *cur_entry;
 2435         struct xpt_task *task;
 2436         uint32_t added;
 2437 
 2438         task = (struct xpt_task *)context;
 2439         cur_entry = (struct async_node *)task->data1;
 2440         added = task->data2;
 2441 
 2442         if ((added & AC_FOUND_DEVICE) != 0) {
 2443                 /*
 2444                  * Get this peripheral up to date with all
 2445                  * the currently existing devices.
 2446                  */
 2447                 xpt_for_all_devices(xptsetasyncfunc, cur_entry);
 2448         }
 2449         if ((added & AC_PATH_REGISTERED) != 0) {
 2450                 /*
 2451                  * Get this peripheral up to date with all
 2452                  * the currently existing busses.
 2453                  */
 2454                 xpt_for_all_busses(xptsetasyncbusfunc, cur_entry);
 2455         }
 2456 
 2457         free(task, M_CAMXPT);
 2458 }
 2459 
 2460 void
 2461 xpt_action(union ccb *start_ccb)
 2462 {
 2463 
 2464         CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_action\n"));
 2465 
 2466         start_ccb->ccb_h.status = CAM_REQ_INPROG;
 2467         (*(start_ccb->ccb_h.path->bus->xport->action))(start_ccb);
 2468 }
 2469 
 2470 void
 2471 xpt_action_default(union ccb *start_ccb)
 2472 {
 2473 
 2474         CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_action_default\n"));
 2475 
 2476 
 2477         switch (start_ccb->ccb_h.func_code) {
 2478         case XPT_SCSI_IO:
 2479         {
 2480                 struct cam_ed *device;
 2481 #ifdef CAMDEBUG
 2482                 char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
 2483                 struct cam_path *path;
 2484 
 2485                 path = start_ccb->ccb_h.path;
 2486 #endif
 2487 
 2488                 /*
 2489                  * For the sake of compatibility with SCSI-1
 2490                  * devices that may not understand the identify
 2491                  * message, we include lun information in the
 2492                  * second byte of all commands.  SCSI-1 specifies
 2493                  * that luns are a 3 bit value and reserves only 3
 2494                  * bits for lun information in the CDB.  Later
 2495                  * revisions of the SCSI spec allow for more than 8
 2496                  * luns, but have deprecated lun information in the
 2497                  * CDB.  So, if the lun won't fit, we must omit.
 2498                  *
 2499                  * Also be aware that during initial probing for devices,
 2500                  * the inquiry information is unknown but initialized to 0.
 2501                  * This means that this code will be exercised while probing
 2502                  * devices with an ANSI revision greater than 2.
 2503                  */
 2504                 device = start_ccb->ccb_h.path->device;
 2505                 if (device->protocol_version <= SCSI_REV_2
 2506                  && start_ccb->ccb_h.target_lun < 8
 2507                  && (start_ccb->ccb_h.flags & CAM_CDB_POINTER) == 0) {
 2508 
 2509                         start_ccb->csio.cdb_io.cdb_bytes[1] |=
 2510                             start_ccb->ccb_h.target_lun << 5;
 2511                 }
 2512                 start_ccb->csio.scsi_status = SCSI_STATUS_OK;
 2513                 CAM_DEBUG(path, CAM_DEBUG_CDB,("%s. CDB: %s\n",
 2514                           scsi_op_desc(start_ccb->csio.cdb_io.cdb_bytes[0],
 2515                                        &path->device->inq_data),
 2516                           scsi_cdb_string(start_ccb->csio.cdb_io.cdb_bytes,
 2517                                           cdb_str, sizeof(cdb_str))));
 2518         }
 2519         /* FALLTHROUGH */
 2520         case XPT_TARGET_IO:
 2521         case XPT_CONT_TARGET_IO:
 2522                 start_ccb->csio.sense_resid = 0;
 2523                 start_ccb->csio.resid = 0;
 2524                 /* FALLTHROUGH */
 2525         case XPT_ATA_IO:
 2526                 if (start_ccb->ccb_h.func_code == XPT_ATA_IO) {
 2527                         start_ccb->ataio.resid = 0;
 2528                 }
 2529         case XPT_RESET_DEV:
 2530         case XPT_ENG_EXEC:
 2531         {
 2532                 struct cam_path *path;
 2533                 int runq;
 2534 
 2535                 path = start_ccb->ccb_h.path;
 2536 
 2537                 cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb);
 2538                 if (path->device->ccbq.queue.qfrozen_cnt == 0)
 2539                         runq = xpt_schedule_dev_sendq(path->bus, path->device);
 2540                 else
 2541                         runq = 0;
 2542                 if (runq != 0)
 2543                         xpt_run_dev_sendq(path->bus);
 2544                 break;
 2545         }
 2546         case XPT_CALC_GEOMETRY:
 2547         {
 2548                 struct cam_sim *sim;
 2549 
 2550                 /* Filter out garbage */
 2551                 if (start_ccb->ccg.block_size == 0
 2552                  || start_ccb->ccg.volume_size == 0) {
 2553                         start_ccb->ccg.cylinders = 0;
 2554                         start_ccb->ccg.heads = 0;
 2555                         start_ccb->ccg.secs_per_track = 0;
 2556                         start_ccb->ccb_h.status = CAM_REQ_CMP;
 2557                         break;
 2558                 }
 2559 #ifdef PC98
 2560                 /*
 2561                  * In a PC-98 system, geometry translation depens on
 2562                  * the "real" device geometry obtained from mode page 4.
 2563                  * SCSI geometry translation is performed in the
 2564                  * initialization routine of the SCSI BIOS and the result
 2565                  * stored in host memory.  If the translation is available
 2566                  * in host memory, use it.  If not, rely on the default
 2567                  * translation the device driver performs.
 2568                  */
 2569                 if (scsi_da_bios_params(&start_ccb->ccg) != 0) {
 2570                         start_ccb->ccb_h.status = CAM_REQ_CMP;
 2571                         break;
 2572                 }
 2573 #endif
 2574                 sim = start_ccb->ccb_h.path->bus->sim;
 2575                 (*(sim->sim_action))(sim, start_ccb);
 2576                 break;
 2577         }
 2578         case XPT_ABORT:
 2579         {
 2580                 union ccb* abort_ccb;
 2581 
 2582                 abort_ccb = start_ccb->cab.abort_ccb;
 2583                 if (XPT_FC_IS_DEV_QUEUED(abort_ccb)) {
 2584 
 2585                         if (abort_ccb->ccb_h.pinfo.index >= 0) {
 2586                                 struct cam_ccbq *ccbq;
 2587 
 2588                                 ccbq = &abort_ccb->ccb_h.path->device->ccbq;
 2589                                 cam_ccbq_remove_ccb(ccbq, abort_ccb);
 2590                                 abort_ccb->ccb_h.status =
 2591                                     CAM_REQ_ABORTED|CAM_DEV_QFRZN;
 2592                                 xpt_freeze_devq(abort_ccb->ccb_h.path, 1);
 2593                                 xpt_done(abort_ccb);
 2594                                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 2595                                 break;
 2596                         }
 2597                         if (abort_ccb->ccb_h.pinfo.index == CAM_UNQUEUED_INDEX
 2598                          && (abort_ccb->ccb_h.status & CAM_SIM_QUEUED) == 0) {
 2599                                 /*
 2600                                  * We've caught this ccb en route to
 2601                                  * the SIM.  Flag it for abort and the
 2602                                  * SIM will do so just before starting
 2603                                  * real work on the CCB.
 2604                                  */
 2605                                 abort_ccb->ccb_h.status =
 2606                                     CAM_REQ_ABORTED|CAM_DEV_QFRZN;
 2607                                 xpt_freeze_devq(abort_ccb->ccb_h.path, 1);
 2608                                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 2609                                 break;
 2610                         }
 2611                 }
 2612                 if (XPT_FC_IS_QUEUED(abort_ccb)
 2613                  && (abort_ccb->ccb_h.pinfo.index == CAM_DONEQ_INDEX)) {
 2614                         /*
 2615                          * It's already completed but waiting
 2616                          * for our SWI to get to it.
 2617                          */
 2618                         start_ccb->ccb_h.status = CAM_UA_ABORT;
 2619                         break;
 2620                 }
 2621                 /*
 2622                  * If we weren't able to take care of the abort request
 2623                  * in the XPT, pass the request down to the SIM for processing.
 2624                  */
 2625         }
 2626         /* FALLTHROUGH */
 2627         case XPT_ACCEPT_TARGET_IO:
 2628         case XPT_EN_LUN:
 2629         case XPT_IMMED_NOTIFY:
 2630         case XPT_NOTIFY_ACK:
 2631         case XPT_RESET_BUS:
 2632         case XPT_IMMEDIATE_NOTIFY:
 2633         case XPT_NOTIFY_ACKNOWLEDGE:
 2634         case XPT_GET_SIM_KNOB:
 2635         case XPT_SET_SIM_KNOB:
 2636         {
 2637                 struct cam_sim *sim;
 2638 
 2639                 sim = start_ccb->ccb_h.path->bus->sim;
 2640                 (*(sim->sim_action))(sim, start_ccb);
 2641                 break;
 2642         }
 2643         case XPT_PATH_INQ:
 2644         {
 2645                 struct cam_sim *sim;
 2646 
 2647                 sim = start_ccb->ccb_h.path->bus->sim;
 2648                 (*(sim->sim_action))(sim, start_ccb);
 2649                 break;
 2650         }
 2651         case XPT_PATH_STATS:
 2652                 start_ccb->cpis.last_reset =
 2653                         start_ccb->ccb_h.path->bus->last_reset;
 2654                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 2655                 break;
 2656         case XPT_GDEV_TYPE:
 2657         {
 2658                 struct cam_ed *dev;
 2659 
 2660                 dev = start_ccb->ccb_h.path->device;
 2661                 if ((dev->flags & CAM_DEV_UNCONFIGURED) != 0) {
 2662                         start_ccb->ccb_h.status = CAM_DEV_NOT_THERE;
 2663                 } else {
 2664                         struct ccb_getdev *cgd;
 2665                         struct cam_eb *bus;
 2666                         struct cam_et *tar;
 2667 
 2668                         cgd = &start_ccb->cgd;
 2669                         bus = cgd->ccb_h.path->bus;
 2670                         tar = cgd->ccb_h.path->target;
 2671                         cgd->protocol = dev->protocol;
 2672                         cgd->inq_data = dev->inq_data;
 2673                         cgd->ident_data = dev->ident_data;
 2674                         cgd->inq_flags = dev->inq_flags;
 2675                         cgd->ccb_h.status = CAM_REQ_CMP;
 2676                         cgd->serial_num_len = dev->serial_num_len;
 2677                         if ((dev->serial_num_len > 0)
 2678                          && (dev->serial_num != NULL))
 2679                                 bcopy(dev->serial_num, cgd->serial_num,
 2680                                       dev->serial_num_len);
 2681                 }
 2682                 break;
 2683         }
 2684         case XPT_GDEV_STATS:
 2685         {
 2686                 struct cam_ed *dev;
 2687 
 2688                 dev = start_ccb->ccb_h.path->device;
 2689                 if ((dev->flags & CAM_DEV_UNCONFIGURED) != 0) {
 2690                         start_ccb->ccb_h.status = CAM_DEV_NOT_THERE;
 2691                 } else {
 2692                         struct ccb_getdevstats *cgds;
 2693                         struct cam_eb *bus;
 2694                         struct cam_et *tar;
 2695 
 2696                         cgds = &start_ccb->cgds;
 2697                         bus = cgds->ccb_h.path->bus;
 2698                         tar = cgds->ccb_h.path->target;
 2699                         cgds->dev_openings = dev->ccbq.dev_openings;
 2700                         cgds->dev_active = dev->ccbq.dev_active;
 2701                         cgds->devq_openings = dev->ccbq.devq_openings;
 2702                         cgds->devq_queued = dev->ccbq.queue.entries;
 2703                         cgds->held = dev->ccbq.held;
 2704                         cgds->last_reset = tar->last_reset;
 2705                         cgds->maxtags = dev->maxtags;
 2706                         cgds->mintags = dev->mintags;
 2707                         if (timevalcmp(&tar->last_reset, &bus->last_reset, <))
 2708                                 cgds->last_reset = bus->last_reset;
 2709                         cgds->ccb_h.status = CAM_REQ_CMP;
 2710                 }
 2711                 break;
 2712         }
 2713         case XPT_GDEVLIST:
 2714         {
 2715                 struct cam_periph       *nperiph;
 2716                 struct periph_list      *periph_head;
 2717                 struct ccb_getdevlist   *cgdl;
 2718                 u_int                   i;
 2719                 struct cam_ed           *device;
 2720                 int                     found;
 2721 
 2722 
 2723                 found = 0;
 2724 
 2725                 /*
 2726                  * Don't want anyone mucking with our data.
 2727                  */
 2728                 device = start_ccb->ccb_h.path->device;
 2729                 periph_head = &device->periphs;
 2730                 cgdl = &start_ccb->cgdl;
 2731 
 2732                 /*
 2733                  * Check and see if the list has changed since the user
 2734                  * last requested a list member.  If so, tell them that the
 2735                  * list has changed, and therefore they need to start over
 2736                  * from the beginning.
 2737                  */
 2738                 if ((cgdl->index != 0) &&
 2739                     (cgdl->generation != device->generation)) {
 2740                         cgdl->status = CAM_GDEVLIST_LIST_CHANGED;
 2741                         break;
 2742                 }
 2743 
 2744                 /*
 2745                  * Traverse the list of peripherals and attempt to find
 2746                  * the requested peripheral.
 2747                  */
 2748                 for (nperiph = SLIST_FIRST(periph_head), i = 0;
 2749                      (nperiph != NULL) && (i <= cgdl->index);
 2750                      nperiph = SLIST_NEXT(nperiph, periph_links), i++) {
 2751                         if (i == cgdl->index) {
 2752                                 strncpy(cgdl->periph_name,
 2753                                         nperiph->periph_name,
 2754                                         DEV_IDLEN);
 2755                                 cgdl->unit_number = nperiph->unit_number;
 2756                                 found = 1;
 2757                         }
 2758                 }
 2759                 if (found == 0) {
 2760                         cgdl->status = CAM_GDEVLIST_ERROR;
 2761                         break;
 2762                 }
 2763 
 2764                 if (nperiph == NULL)
 2765                         cgdl->status = CAM_GDEVLIST_LAST_DEVICE;
 2766                 else
 2767                         cgdl->status = CAM_GDEVLIST_MORE_DEVS;
 2768 
 2769                 cgdl->index++;
 2770                 cgdl->generation = device->generation;
 2771 
 2772                 cgdl->ccb_h.status = CAM_REQ_CMP;
 2773                 break;
 2774         }
 2775         case XPT_DEV_MATCH:
 2776         {
 2777                 dev_pos_type position_type;
 2778                 struct ccb_dev_match *cdm;
 2779 
 2780                 cdm = &start_ccb->cdm;
 2781 
 2782                 /*
 2783                  * There are two ways of getting at information in the EDT.
 2784                  * The first way is via the primary EDT tree.  It starts
 2785                  * with a list of busses, then a list of targets on a bus,
 2786                  * then devices/luns on a target, and then peripherals on a
 2787                  * device/lun.  The "other" way is by the peripheral driver
 2788                  * lists.  The peripheral driver lists are organized by
 2789                  * peripheral driver.  (obviously)  So it makes sense to
 2790                  * use the peripheral driver list if the user is looking
 2791                  * for something like "da1", or all "da" devices.  If the
 2792                  * user is looking for something on a particular bus/target
 2793                  * or lun, it's generally better to go through the EDT tree.
 2794                  */
 2795 
 2796                 if (cdm->pos.position_type != CAM_DEV_POS_NONE)
 2797                         position_type = cdm->pos.position_type;
 2798                 else {
 2799                         u_int i;
 2800 
 2801                         position_type = CAM_DEV_POS_NONE;
 2802 
 2803                         for (i = 0; i < cdm->num_patterns; i++) {
 2804                                 if ((cdm->patterns[i].type == DEV_MATCH_BUS)
 2805                                  ||(cdm->patterns[i].type == DEV_MATCH_DEVICE)){
 2806                                         position_type = CAM_DEV_POS_EDT;
 2807                                         break;
 2808                                 }
 2809                         }
 2810 
 2811                         if (cdm->num_patterns == 0)
 2812                                 position_type = CAM_DEV_POS_EDT;
 2813                         else if (position_type == CAM_DEV_POS_NONE)
 2814                                 position_type = CAM_DEV_POS_PDRV;
 2815                 }
 2816 
 2817                 switch(position_type & CAM_DEV_POS_TYPEMASK) {
 2818                 case CAM_DEV_POS_EDT:
 2819                         xptedtmatch(cdm);
 2820                         break;
 2821                 case CAM_DEV_POS_PDRV:
 2822                         xptperiphlistmatch(cdm);
 2823                         break;
 2824                 default:
 2825                         cdm->status = CAM_DEV_MATCH_ERROR;
 2826                         break;
 2827                 }
 2828 
 2829                 if (cdm->status == CAM_DEV_MATCH_ERROR)
 2830                         start_ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 2831                 else
 2832                         start_ccb->ccb_h.status = CAM_REQ_CMP;
 2833 
 2834                 break;
 2835         }
 2836         case XPT_SASYNC_CB:
 2837         {
 2838                 struct ccb_setasync *csa;
 2839                 struct async_node *cur_entry;
 2840                 struct async_list *async_head;
 2841                 u_int32_t added;
 2842 
 2843                 csa = &start_ccb->csa;
 2844                 added = csa->event_enable;
 2845                 async_head = &csa->ccb_h.path->device->asyncs;
 2846 
 2847                 /*
 2848                  * If there is already an entry for us, simply
 2849                  * update it.
 2850                  */
 2851                 cur_entry = SLIST_FIRST(async_head);
 2852                 while (cur_entry != NULL) {
 2853                         if ((cur_entry->callback_arg == csa->callback_arg)
 2854                          && (cur_entry->callback == csa->callback))
 2855                                 break;
 2856                         cur_entry = SLIST_NEXT(cur_entry, links);
 2857                 }
 2858 
 2859                 if (cur_entry != NULL) {
 2860                         /*
 2861                          * If the request has no flags set,
 2862                          * remove the entry.
 2863                          */
 2864                         added &= ~cur_entry->event_enable;
 2865                         if (csa->event_enable == 0) {
 2866                                 SLIST_REMOVE(async_head, cur_entry,
 2867                                              async_node, links);
 2868                                 csa->ccb_h.path->device->refcount--;
 2869                                 free(cur_entry, M_CAMXPT);
 2870                         } else {
 2871                                 cur_entry->event_enable = csa->event_enable;
 2872                         }
 2873                 } else {
 2874                         cur_entry = malloc(sizeof(*cur_entry), M_CAMXPT,
 2875                                            M_NOWAIT);
 2876                         if (cur_entry == NULL) {
 2877                                 csa->ccb_h.status = CAM_RESRC_UNAVAIL;
 2878                                 break;
 2879                         }
 2880                         cur_entry->event_enable = csa->event_enable;
 2881                         cur_entry->callback_arg = csa->callback_arg;
 2882                         cur_entry->callback = csa->callback;
 2883                         SLIST_INSERT_HEAD(async_head, cur_entry, links);
 2884                         csa->ccb_h.path->device->refcount++;
 2885                 }
 2886 
 2887                 /*
 2888                  * Need to decouple this operation via a taqskqueue so that
 2889                  * the locking doesn't become a mess.
 2890                  */
 2891                 if ((added & (AC_FOUND_DEVICE | AC_PATH_REGISTERED)) != 0) {
 2892                         struct xpt_task *task;
 2893 
 2894                         task = malloc(sizeof(struct xpt_task), M_CAMXPT,
 2895                                       M_NOWAIT);
 2896                         if (task == NULL) {
 2897                                 csa->ccb_h.status = CAM_RESRC_UNAVAIL;
 2898                                 break;
 2899                         }
 2900 
 2901                         TASK_INIT(&task->task, 0, xpt_action_sasync_cb, task);
 2902                         task->data1 = cur_entry;
 2903                         task->data2 = added;
 2904                         taskqueue_enqueue(taskqueue_thread, &task->task);
 2905                 }
 2906 
 2907                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 2908                 break;
 2909         }
 2910         case XPT_REL_SIMQ:
 2911         {
 2912                 struct ccb_relsim *crs;
 2913                 struct cam_ed *dev;
 2914 
 2915                 crs = &start_ccb->crs;
 2916                 dev = crs->ccb_h.path->device;
 2917                 if (dev == NULL) {
 2918 
 2919                         crs->ccb_h.status = CAM_DEV_NOT_THERE;
 2920                         break;
 2921                 }
 2922 
 2923                 if ((crs->release_flags & RELSIM_ADJUST_OPENINGS) != 0) {
 2924 
 2925                         if (INQ_DATA_TQ_ENABLED(&dev->inq_data)) {
 2926                                 /* Don't ever go below one opening */
 2927                                 if (crs->openings > 0) {
 2928                                         xpt_dev_ccbq_resize(crs->ccb_h.path,
 2929                                                             crs->openings);
 2930 
 2931                                         if (bootverbose) {
 2932                                                 xpt_print(crs->ccb_h.path,
 2933                                                     "tagged openings now %d\n",
 2934                                                     crs->openings);
 2935                                         }
 2936                                 }
 2937                         }
 2938                 }
 2939 
 2940                 if ((crs->release_flags & RELSIM_RELEASE_AFTER_TIMEOUT) != 0) {
 2941 
 2942                         if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) {
 2943 
 2944                                 /*
 2945                                  * Just extend the old timeout and decrement
 2946                                  * the freeze count so that a single timeout
 2947                                  * is sufficient for releasing the queue.
 2948                                  */
 2949                                 start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE;
 2950                                 callout_stop(&dev->callout);
 2951                         } else {
 2952 
 2953                                 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
 2954                         }
 2955 
 2956                         callout_reset(&dev->callout,
 2957                             (crs->release_timeout * hz) / 1000,
 2958                             xpt_release_devq_timeout, dev);
 2959 
 2960                         dev->flags |= CAM_DEV_REL_TIMEOUT_PENDING;
 2961 
 2962                 }
 2963 
 2964                 if ((crs->release_flags & RELSIM_RELEASE_AFTER_CMDCMPLT) != 0) {
 2965 
 2966                         if ((dev->flags & CAM_DEV_REL_ON_COMPLETE) != 0) {
 2967                                 /*
 2968                                  * Decrement the freeze count so that a single
 2969                                  * completion is still sufficient to unfreeze
 2970                                  * the queue.
 2971                                  */
 2972                                 start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE;
 2973                         } else {
 2974 
 2975                                 dev->flags |= CAM_DEV_REL_ON_COMPLETE;
 2976                                 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
 2977                         }
 2978                 }
 2979 
 2980                 if ((crs->release_flags & RELSIM_RELEASE_AFTER_QEMPTY) != 0) {
 2981 
 2982                         if ((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0
 2983                          || (dev->ccbq.dev_active == 0)) {
 2984 
 2985                                 start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE;
 2986                         } else {
 2987 
 2988                                 dev->flags |= CAM_DEV_REL_ON_QUEUE_EMPTY;
 2989                                 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
 2990                         }
 2991                 }
 2992 
 2993                 if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) == 0) {
 2994 
 2995                         xpt_release_devq(crs->ccb_h.path, /*count*/1,
 2996                                          /*run_queue*/TRUE);
 2997                 }
 2998                 start_ccb->crs.qfrozen_cnt = dev->ccbq.queue.qfrozen_cnt;
 2999                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 3000                 break;
 3001         }
 3002         case XPT_DEBUG: {
 3003 #ifdef CAMDEBUG
 3004 #ifdef CAM_DEBUG_DELAY
 3005                 cam_debug_delay = CAM_DEBUG_DELAY;
 3006 #endif
 3007                 cam_dflags = start_ccb->cdbg.flags;
 3008                 if (cam_dpath != NULL) {
 3009                         xpt_free_path(cam_dpath);
 3010                         cam_dpath = NULL;
 3011                 }
 3012 
 3013                 if (cam_dflags != CAM_DEBUG_NONE) {
 3014                         if (xpt_create_path(&cam_dpath, xpt_periph,
 3015                                             start_ccb->ccb_h.path_id,
 3016                                             start_ccb->ccb_h.target_id,
 3017                                             start_ccb->ccb_h.target_lun) !=
 3018                                             CAM_REQ_CMP) {
 3019                                 start_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 3020                                 cam_dflags = CAM_DEBUG_NONE;
 3021                         } else {
 3022                                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 3023                                 xpt_print(cam_dpath, "debugging flags now %x\n",
 3024                                     cam_dflags);
 3025                         }
 3026                 } else {
 3027                         cam_dpath = NULL;
 3028                         start_ccb->ccb_h.status = CAM_REQ_CMP;
 3029                 }
 3030 #else /* !CAMDEBUG */
 3031                 start_ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 3032 #endif /* CAMDEBUG */
 3033                 break;
 3034         }
 3035         case XPT_NOOP:
 3036                 if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0)
 3037                         xpt_freeze_devq(start_ccb->ccb_h.path, 1);
 3038                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 3039                 break;
 3040         default:
 3041         case XPT_SDEV_TYPE:
 3042         case XPT_TERM_IO:
 3043         case XPT_ENG_INQ:
 3044                 /* XXX Implement */
 3045                 start_ccb->ccb_h.status = CAM_PROVIDE_FAIL;
 3046                 break;
 3047         }
 3048 }
 3049 
 3050 void
 3051 xpt_polled_action(union ccb *start_ccb)
 3052 {
 3053         u_int32_t timeout;
 3054         struct    cam_sim *sim;
 3055         struct    cam_devq *devq;
 3056         struct    cam_ed *dev;
 3057 
 3058 
 3059         timeout = start_ccb->ccb_h.timeout;
 3060         sim = start_ccb->ccb_h.path->bus->sim;
 3061         devq = sim->devq;
 3062         dev = start_ccb->ccb_h.path->device;
 3063 
 3064         mtx_assert(sim->mtx, MA_OWNED);
 3065 
 3066         /*
 3067          * Steal an opening so that no other queued requests
 3068          * can get it before us while we simulate interrupts.
 3069          */
 3070         dev->ccbq.devq_openings--;
 3071         dev->ccbq.dev_openings--;
 3072 
 3073         while(((devq != NULL && devq->send_openings <= 0) ||
 3074            dev->ccbq.dev_openings < 0) && (--timeout > 0)) {
 3075                 DELAY(1000);
 3076                 (*(sim->sim_poll))(sim);
 3077                 camisr_runqueue(&sim->sim_doneq);
 3078         }
 3079 
 3080         dev->ccbq.devq_openings++;
 3081         dev->ccbq.dev_openings++;
 3082 
 3083         if (timeout != 0) {
 3084                 xpt_action(start_ccb);
 3085                 while(--timeout > 0) {
 3086                         (*(sim->sim_poll))(sim);
 3087                         camisr_runqueue(&sim->sim_doneq);
 3088                         if ((start_ccb->ccb_h.status  & CAM_STATUS_MASK)
 3089                             != CAM_REQ_INPROG)
 3090                                 break;
 3091                         DELAY(1000);
 3092                 }
 3093                 if (timeout == 0) {
 3094                         /*
 3095                          * XXX Is it worth adding a sim_timeout entry
 3096                          * point so we can attempt recovery?  If
 3097                          * this is only used for dumps, I don't think
 3098                          * it is.
 3099                          */
 3100                         start_ccb->ccb_h.status = CAM_CMD_TIMEOUT;
 3101                 }
 3102         } else {
 3103                 start_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 3104         }
 3105 }
 3106 
 3107 /*
 3108  * Schedule a peripheral driver to receive a ccb when it's
 3109  * target device has space for more transactions.
 3110  */
 3111 void
 3112 xpt_schedule(struct cam_periph *perph, u_int32_t new_priority)
 3113 {
 3114         struct cam_ed *device;
 3115         int runq;
 3116 
 3117         mtx_assert(perph->sim->mtx, MA_OWNED);
 3118 
 3119         CAM_DEBUG(perph->path, CAM_DEBUG_TRACE, ("xpt_schedule\n"));
 3120         device = perph->path->device;
 3121         if (periph_is_queued(perph)) {
 3122                 /* Simply reorder based on new priority */
 3123                 CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
 3124                           ("   change priority to %d\n", new_priority));
 3125                 if (new_priority < perph->pinfo.priority) {
 3126                         camq_change_priority(&device->drvq,
 3127                                              perph->pinfo.index,
 3128                                              new_priority);
 3129                 }
 3130                 runq = 0;
 3131         } else {
 3132                 /* New entry on the queue */
 3133                 CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
 3134                           ("   added periph to queue\n"));
 3135                 perph->pinfo.priority = new_priority;
 3136                 perph->pinfo.generation = ++device->drvq.generation;
 3137                 camq_insert(&device->drvq, &perph->pinfo);
 3138                 runq = xpt_schedule_dev_allocq(perph->path->bus, device);
 3139         }
 3140         if (runq != 0) {
 3141                 CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
 3142                           ("   calling xpt_run_devq\n"));
 3143                 xpt_run_dev_allocq(perph->path->bus);
 3144         }
 3145 }
 3146 
 3147 
 3148 /*
 3149  * Schedule a device to run on a given queue.
 3150  * If the device was inserted as a new entry on the queue,
 3151  * return 1 meaning the device queue should be run. If we
 3152  * were already queued, implying someone else has already
 3153  * started the queue, return 0 so the caller doesn't attempt
 3154  * to run the queue.
 3155  */
 3156 int
 3157 xpt_schedule_dev(struct camq *queue, cam_pinfo *pinfo,
 3158                  u_int32_t new_priority)
 3159 {
 3160         int retval;
 3161         u_int32_t old_priority;
 3162 
 3163         CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_schedule_dev\n"));
 3164 
 3165         old_priority = pinfo->priority;
 3166 
 3167         /*
 3168          * Are we already queued?
 3169          */
 3170         if (pinfo->index != CAM_UNQUEUED_INDEX) {
 3171                 /* Simply reorder based on new priority */
 3172                 if (new_priority < old_priority) {
 3173                         camq_change_priority(queue, pinfo->index,
 3174                                              new_priority);
 3175                         CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3176                                         ("changed priority to %d\n",
 3177                                          new_priority));
 3178                 }
 3179                 retval = 0;
 3180         } else {
 3181                 /* New entry on the queue */
 3182                 if (new_priority < old_priority)
 3183                         pinfo->priority = new_priority;
 3184 
 3185                 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3186                                 ("Inserting onto queue\n"));
 3187                 pinfo->generation = ++queue->generation;
 3188                 camq_insert(queue, pinfo);
 3189                 retval = 1;
 3190         }
 3191         return (retval);
 3192 }
 3193 
 3194 static void
 3195 xpt_run_dev_allocq(struct cam_eb *bus)
 3196 {
 3197         struct  cam_devq *devq;
 3198 
 3199         CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_allocq\n"));
 3200         devq = bus->sim->devq;
 3201 
 3202         CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3203                         ("   qfrozen_cnt == 0x%x, entries == %d, "
 3204                          "openings == %d, active == %d\n",
 3205                          devq->alloc_queue.qfrozen_cnt,
 3206                          devq->alloc_queue.entries,
 3207                          devq->alloc_openings,
 3208                          devq->alloc_active));
 3209 
 3210         devq->alloc_queue.qfrozen_cnt++;
 3211         while ((devq->alloc_queue.entries > 0)
 3212             && (devq->alloc_openings > 0)
 3213             && (devq->alloc_queue.qfrozen_cnt <= 1)) {
 3214                 struct  cam_ed_qinfo *qinfo;
 3215                 struct  cam_ed *device;
 3216                 union   ccb *work_ccb;
 3217                 struct  cam_periph *drv;
 3218                 struct  camq *drvq;
 3219 
 3220                 qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->alloc_queue,
 3221                                                            CAMQ_HEAD);
 3222                 device = qinfo->device;
 3223 
 3224                 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3225                                 ("running device %p\n", device));
 3226 
 3227                 drvq = &device->drvq;
 3228 
 3229 #ifdef CAMDEBUG
 3230                 if (drvq->entries <= 0) {
 3231                         panic("xpt_run_dev_allocq: "
 3232                               "Device on queue without any work to do");
 3233                 }
 3234 #endif
 3235                 if ((work_ccb = xpt_get_ccb(device)) != NULL) {
 3236                         devq->alloc_openings--;
 3237                         devq->alloc_active++;
 3238                         drv = (struct cam_periph*)camq_remove(drvq, CAMQ_HEAD);
 3239                         xpt_setup_ccb(&work_ccb->ccb_h, drv->path,
 3240                                       drv->pinfo.priority);
 3241                         CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3242                                         ("calling periph start\n"));
 3243                         drv->periph_start(drv, work_ccb);
 3244                 } else {
 3245                         /*
 3246                          * Malloc failure in alloc_ccb
 3247                          */
 3248                         /*
 3249                          * XXX add us to a list to be run from free_ccb
 3250                          * if we don't have any ccbs active on this
 3251                          * device queue otherwise we may never get run
 3252                          * again.
 3253                          */
 3254                         break;
 3255                 }
 3256 
 3257                 if (drvq->entries > 0) {
 3258                         /* We have more work.  Attempt to reschedule */
 3259                         xpt_schedule_dev_allocq(bus, device);
 3260                 }
 3261         }
 3262         devq->alloc_queue.qfrozen_cnt--;
 3263 }
 3264 
 3265 void
 3266 xpt_run_dev_sendq(struct cam_eb *bus)
 3267 {
 3268         struct  cam_devq *devq;
 3269 
 3270         CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_sendq\n"));
 3271 
 3272         devq = bus->sim->devq;
 3273 
 3274         devq->send_queue.qfrozen_cnt++;
 3275         while ((devq->send_queue.entries > 0)
 3276             && (devq->send_openings > 0)
 3277             && (devq->send_queue.qfrozen_cnt <= 1)) {
 3278                 struct  cam_ed_qinfo *qinfo;
 3279                 struct  cam_ed *device;
 3280                 union ccb *work_ccb;
 3281                 struct  cam_sim *sim;
 3282 
 3283                 qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->send_queue,
 3284                                                            CAMQ_HEAD);
 3285                 device = qinfo->device;
 3286 
 3287                 /*
 3288                  * If the device has been "frozen", don't attempt
 3289                  * to run it.
 3290                  */
 3291                 if (device->ccbq.queue.qfrozen_cnt > 0) {
 3292                         continue;
 3293                 }
 3294 
 3295                 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3296                                 ("running device %p\n", device));
 3297 
 3298                 work_ccb = cam_ccbq_peek_ccb(&device->ccbq, CAMQ_HEAD);
 3299                 if (work_ccb == NULL) {
 3300                         printf("device on run queue with no ccbs???\n");
 3301                         continue;
 3302                 }
 3303 
 3304                 if ((work_ccb->ccb_h.flags & CAM_HIGH_POWER) != 0) {
 3305 
 3306                         mtx_lock(&xsoftc.xpt_lock);
 3307                         if (xsoftc.num_highpower <= 0) {
 3308                                 /*
 3309                                  * We got a high power command, but we
 3310                                  * don't have any available slots.  Freeze
 3311                                  * the device queue until we have a slot
 3312                                  * available.
 3313                                  */
 3314                                 device->ccbq.queue.qfrozen_cnt++;
 3315                                 STAILQ_INSERT_TAIL(&xsoftc.highpowerq,
 3316                                                    &work_ccb->ccb_h,
 3317                                                    xpt_links.stqe);
 3318 
 3319                                 mtx_unlock(&xsoftc.xpt_lock);
 3320                                 continue;
 3321                         } else {
 3322                                 /*
 3323                                  * Consume a high power slot while
 3324                                  * this ccb runs.
 3325                                  */
 3326                                 xsoftc.num_highpower--;
 3327                         }
 3328                         mtx_unlock(&xsoftc.xpt_lock);
 3329                 }
 3330                 cam_ccbq_remove_ccb(&device->ccbq, work_ccb);
 3331                 cam_ccbq_send_ccb(&device->ccbq, work_ccb);
 3332 
 3333                 devq->send_openings--;
 3334                 devq->send_active++;
 3335 
 3336                 if (device->ccbq.queue.entries > 0)
 3337                         xpt_schedule_dev_sendq(bus, device);
 3338 
 3339                 if (work_ccb && (work_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0){
 3340                         /*
 3341                          * The client wants to freeze the queue
 3342                          * after this CCB is sent.
 3343                          */
 3344                         device->ccbq.queue.qfrozen_cnt++;
 3345                 }
 3346 
 3347                 /* In Target mode, the peripheral driver knows best... */
 3348                 if (work_ccb->ccb_h.func_code == XPT_SCSI_IO) {
 3349                         if ((device->inq_flags & SID_CmdQue) != 0
 3350                          && work_ccb->csio.tag_action != CAM_TAG_ACTION_NONE)
 3351                                 work_ccb->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 3352                         else
 3353                                 /*
 3354                                  * Clear this in case of a retried CCB that
 3355                                  * failed due to a rejected tag.
 3356                                  */
 3357                                 work_ccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
 3358                 }
 3359 
 3360                 /*
 3361                  * Device queues can be shared among multiple sim instances
 3362                  * that reside on different busses.  Use the SIM in the queue
 3363                  * CCB's path, rather than the one in the bus that was passed
 3364                  * into this function.
 3365                  */
 3366                 sim = work_ccb->ccb_h.path->bus->sim;
 3367                 (*(sim->sim_action))(sim, work_ccb);
 3368         }
 3369         devq->send_queue.qfrozen_cnt--;
 3370 }
 3371 
 3372 /*
 3373  * This function merges stuff from the slave ccb into the master ccb, while
 3374  * keeping important fields in the master ccb constant.
 3375  */
 3376 void
 3377 xpt_merge_ccb(union ccb *master_ccb, union ccb *slave_ccb)
 3378 {
 3379 
 3380         /*
 3381          * Pull fields that are valid for peripheral drivers to set
 3382          * into the master CCB along with the CCB "payload".
 3383          */
 3384         master_ccb->ccb_h.retry_count = slave_ccb->ccb_h.retry_count;
 3385         master_ccb->ccb_h.func_code = slave_ccb->ccb_h.func_code;
 3386         master_ccb->ccb_h.timeout = slave_ccb->ccb_h.timeout;
 3387         master_ccb->ccb_h.flags = slave_ccb->ccb_h.flags;
 3388         bcopy(&(&slave_ccb->ccb_h)[1], &(&master_ccb->ccb_h)[1],
 3389               sizeof(union ccb) - sizeof(struct ccb_hdr));
 3390 }
 3391 
 3392 void
 3393 xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
 3394 {
 3395 
 3396         CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_setup_ccb\n"));
 3397         ccb_h->pinfo.priority = priority;
 3398         ccb_h->path = path;
 3399         ccb_h->path_id = path->bus->path_id;
 3400         if (path->target)
 3401                 ccb_h->target_id = path->target->target_id;
 3402         else
 3403                 ccb_h->target_id = CAM_TARGET_WILDCARD;
 3404         if (path->device) {
 3405                 ccb_h->target_lun = path->device->lun_id;
 3406                 ccb_h->pinfo.generation = ++path->device->ccbq.queue.generation;
 3407         } else {
 3408                 ccb_h->target_lun = CAM_TARGET_WILDCARD;
 3409         }
 3410         ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
 3411         ccb_h->flags = 0;
 3412 }
 3413 
 3414 /* Path manipulation functions */
 3415 cam_status
 3416 xpt_create_path(struct cam_path **new_path_ptr, struct cam_periph *perph,
 3417                 path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
 3418 {
 3419         struct     cam_path *path;
 3420         cam_status status;
 3421 
 3422         path = (struct cam_path *)malloc(sizeof(*path), M_CAMXPT, M_NOWAIT);
 3423 
 3424         if (path == NULL) {
 3425                 status = CAM_RESRC_UNAVAIL;
 3426                 return(status);
 3427         }
 3428         status = xpt_compile_path(path, perph, path_id, target_id, lun_id);
 3429         if (status != CAM_REQ_CMP) {
 3430                 free(path, M_CAMXPT);
 3431                 path = NULL;
 3432         }
 3433         *new_path_ptr = path;
 3434         return (status);
 3435 }
 3436 
 3437 cam_status
 3438 xpt_create_path_unlocked(struct cam_path **new_path_ptr,
 3439                          struct cam_periph *periph, path_id_t path_id,
 3440                          target_id_t target_id, lun_id_t lun_id)
 3441 {
 3442         struct     cam_path *path;
 3443         struct     cam_eb *bus = NULL;
 3444         cam_status status;
 3445         int        need_unlock = 0;
 3446 
 3447         path = (struct cam_path *)malloc(sizeof(*path), M_CAMXPT, M_WAITOK);
 3448 
 3449         if (path_id != CAM_BUS_WILDCARD) {
 3450                 bus = xpt_find_bus(path_id);
 3451                 if (bus != NULL) {
 3452                         need_unlock = 1;
 3453                         CAM_SIM_LOCK(bus->sim);
 3454                 }
 3455         }
 3456         status = xpt_compile_path(path, periph, path_id, target_id, lun_id);
 3457         if (need_unlock)
 3458                 CAM_SIM_UNLOCK(bus->sim);
 3459         if (status != CAM_REQ_CMP) {
 3460                 free(path, M_CAMXPT);
 3461                 path = NULL;
 3462         }
 3463         *new_path_ptr = path;
 3464         return (status);
 3465 }
 3466 
 3467 cam_status
 3468 xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph,
 3469                  path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
 3470 {
 3471         struct       cam_eb *bus;
 3472         struct       cam_et *target;
 3473         struct       cam_ed *device;
 3474         cam_status   status;
 3475 
 3476         status = CAM_REQ_CMP;   /* Completed without error */
 3477         target = NULL;          /* Wildcarded */
 3478         device = NULL;          /* Wildcarded */
 3479 
 3480         /*
 3481          * We will potentially modify the EDT, so block interrupts
 3482          * that may attempt to create cam paths.
 3483          */
 3484         bus = xpt_find_bus(path_id);
 3485         if (bus == NULL) {
 3486                 status = CAM_PATH_INVALID;
 3487         } else {
 3488                 target = xpt_find_target(bus, target_id);
 3489                 if (target == NULL) {
 3490                         /* Create one */
 3491                         struct cam_et *new_target;
 3492 
 3493                         new_target = xpt_alloc_target(bus, target_id);
 3494                         if (new_target == NULL) {
 3495                                 status = CAM_RESRC_UNAVAIL;
 3496                         } else {
 3497                                 target = new_target;
 3498                         }
 3499                 }
 3500                 if (target != NULL) {
 3501                         device = xpt_find_device(target, lun_id);
 3502                         if (device == NULL) {
 3503                                 /* Create one */
 3504                                 struct cam_ed *new_device;
 3505 
 3506                                 new_device =
 3507                                     (*(bus->xport->alloc_device))(bus,
 3508                                                                       target,
 3509                                                                       lun_id);
 3510                                 if (new_device == NULL) {
 3511                                         status = CAM_RESRC_UNAVAIL;
 3512                                 } else {
 3513                                         device = new_device;
 3514                                 }
 3515                         }
 3516                 }
 3517         }
 3518 
 3519         /*
 3520          * Only touch the user's data if we are successful.
 3521          */
 3522         if (status == CAM_REQ_CMP) {
 3523                 new_path->periph = perph;
 3524                 new_path->bus = bus;
 3525                 new_path->target = target;
 3526                 new_path->device = device;
 3527                 CAM_DEBUG(new_path, CAM_DEBUG_TRACE, ("xpt_compile_path\n"));
 3528         } else {
 3529                 if (device != NULL)
 3530                         xpt_release_device(device);
 3531                 if (target != NULL)
 3532                         xpt_release_target(target);
 3533                 if (bus != NULL)
 3534                         xpt_release_bus(bus);
 3535         }
 3536         return (status);
 3537 }
 3538 
 3539 void
 3540 xpt_release_path(struct cam_path *path)
 3541 {
 3542         CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_release_path\n"));
 3543         if (path->device != NULL) {
 3544                 xpt_release_device(path->device);
 3545                 path->device = NULL;
 3546         }
 3547         if (path->target != NULL) {
 3548                 xpt_release_target(path->target);
 3549                 path->target = NULL;
 3550         }
 3551         if (path->bus != NULL) {
 3552                 xpt_release_bus(path->bus);
 3553                 path->bus = NULL;
 3554         }
 3555 }
 3556 
 3557 void
 3558 xpt_free_path(struct cam_path *path)
 3559 {
 3560 
 3561         CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_free_path\n"));
 3562         xpt_release_path(path);
 3563         free(path, M_CAMXPT);
 3564 }
 3565 
 3566 
 3567 /*
 3568  * Return -1 for failure, 0 for exact match, 1 for match with wildcards
 3569  * in path1, 2 for match with wildcards in path2.
 3570  */
 3571 int
 3572 xpt_path_comp(struct cam_path *path1, struct cam_path *path2)
 3573 {
 3574         int retval = 0;
 3575 
 3576         if (path1->bus != path2->bus) {
 3577                 if (path1->bus->path_id == CAM_BUS_WILDCARD)
 3578                         retval = 1;
 3579                 else if (path2->bus->path_id == CAM_BUS_WILDCARD)
 3580                         retval = 2;
 3581                 else
 3582                         return (-1);
 3583         }
 3584         if (path1->target != path2->target) {
 3585                 if (path1->target->target_id == CAM_TARGET_WILDCARD) {
 3586                         if (retval == 0)
 3587                                 retval = 1;
 3588                 } else if (path2->target->target_id == CAM_TARGET_WILDCARD)
 3589                         retval = 2;
 3590                 else
 3591                         return (-1);
 3592         }
 3593         if (path1->device != path2->device) {
 3594                 if (path1->device->lun_id == CAM_LUN_WILDCARD) {
 3595                         if (retval == 0)
 3596                                 retval = 1;
 3597                 } else if (path2->device->lun_id == CAM_LUN_WILDCARD)
 3598                         retval = 2;
 3599                 else
 3600                         return (-1);
 3601         }
 3602         return (retval);
 3603 }
 3604 
 3605 void
 3606 xpt_print_path(struct cam_path *path)
 3607 {
 3608 
 3609         if (path == NULL)
 3610                 printf("(nopath): ");
 3611         else {
 3612                 if (path->periph != NULL)
 3613                         printf("(%s%d:", path->periph->periph_name,
 3614                                path->periph->unit_number);
 3615                 else
 3616                         printf("(noperiph:");
 3617 
 3618                 if (path->bus != NULL)
 3619                         printf("%s%d:%d:", path->bus->sim->sim_name,
 3620                                path->bus->sim->unit_number,
 3621                                path->bus->sim->bus_id);
 3622                 else
 3623                         printf("nobus:");
 3624 
 3625                 if (path->target != NULL)
 3626                         printf("%d:", path->target->target_id);
 3627                 else
 3628                         printf("X:");
 3629 
 3630                 if (path->device != NULL)
 3631                         printf("%d): ", path->device->lun_id);
 3632                 else
 3633                         printf("X): ");
 3634         }
 3635 }
 3636 
 3637 void
 3638 xpt_print(struct cam_path *path, const char *fmt, ...)
 3639 {
 3640         va_list ap;
 3641         xpt_print_path(path);
 3642         va_start(ap, fmt);
 3643         vprintf(fmt, ap);
 3644         va_end(ap);
 3645 }
 3646 
 3647 int
 3648 xpt_path_string(struct cam_path *path, char *str, size_t str_len)
 3649 {
 3650         struct sbuf sb;
 3651 
 3652 #ifdef INVARIANTS
 3653         if (path != NULL && path->bus != NULL)
 3654                 mtx_assert(path->bus->sim->mtx, MA_OWNED);
 3655 #endif
 3656 
 3657         sbuf_new(&sb, str, str_len, 0);
 3658 
 3659         if (path == NULL)
 3660                 sbuf_printf(&sb, "(nopath): ");
 3661         else {
 3662                 if (path->periph != NULL)
 3663                         sbuf_printf(&sb, "(%s%d:", path->periph->periph_name,
 3664                                     path->periph->unit_number);
 3665                 else
 3666                         sbuf_printf(&sb, "(noperiph:");
 3667 
 3668                 if (path->bus != NULL)
 3669                         sbuf_printf(&sb, "%s%d:%d:", path->bus->sim->sim_name,
 3670                                     path->bus->sim->unit_number,
 3671                                     path->bus->sim->bus_id);
 3672                 else
 3673                         sbuf_printf(&sb, "nobus:");
 3674 
 3675                 if (path->target != NULL)
 3676                         sbuf_printf(&sb, "%d:", path->target->target_id);
 3677                 else
 3678                         sbuf_printf(&sb, "X:");
 3679 
 3680                 if (path->device != NULL)
 3681                         sbuf_printf(&sb, "%d): ", path->device->lun_id);
 3682                 else
 3683                         sbuf_printf(&sb, "X): ");
 3684         }
 3685         sbuf_finish(&sb);
 3686 
 3687         return(sbuf_len(&sb));
 3688 }
 3689 
 3690 path_id_t
 3691 xpt_path_path_id(struct cam_path *path)
 3692 {
 3693         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 3694 
 3695         return(path->bus->path_id);
 3696 }
 3697 
 3698 target_id_t
 3699 xpt_path_target_id(struct cam_path *path)
 3700 {
 3701         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 3702 
 3703         if (path->target != NULL)
 3704                 return (path->target->target_id);
 3705         else
 3706                 return (CAM_TARGET_WILDCARD);
 3707 }
 3708 
 3709 lun_id_t
 3710 xpt_path_lun_id(struct cam_path *path)
 3711 {
 3712         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 3713 
 3714         if (path->device != NULL)
 3715                 return (path->device->lun_id);
 3716         else
 3717                 return (CAM_LUN_WILDCARD);
 3718 }
 3719 
 3720 struct cam_sim *
 3721 xpt_path_sim(struct cam_path *path)
 3722 {
 3723 
 3724         return (path->bus->sim);
 3725 }
 3726 
 3727 struct cam_periph*
 3728 xpt_path_periph(struct cam_path *path)
 3729 {
 3730         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 3731 
 3732         return (path->periph);
 3733 }
 3734 
 3735 /*
 3736  * Release a CAM control block for the caller.  Remit the cost of the structure
 3737  * to the device referenced by the path.  If the this device had no 'credits'
 3738  * and peripheral drivers have registered async callbacks for this notification
 3739  * call them now.
 3740  */
 3741 void
 3742 xpt_release_ccb(union ccb *free_ccb)
 3743 {
 3744         struct   cam_path *path;
 3745         struct   cam_ed *device;
 3746         struct   cam_eb *bus;
 3747         struct   cam_sim *sim;
 3748 
 3749         CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_release_ccb\n"));
 3750         path = free_ccb->ccb_h.path;
 3751         device = path->device;
 3752         bus = path->bus;
 3753         sim = bus->sim;
 3754 
 3755         mtx_assert(sim->mtx, MA_OWNED);
 3756 
 3757         cam_ccbq_release_opening(&device->ccbq);
 3758         if (device->flags & CAM_DEV_RESIZE_QUEUE_NEEDED) {
 3759                 device->flags &= ~CAM_DEV_RESIZE_QUEUE_NEEDED;
 3760                 cam_ccbq_resize(&device->ccbq,
 3761                     device->ccbq.dev_openings + device->ccbq.dev_active);
 3762         }
 3763         if (sim->ccb_count > sim->max_ccbs) {
 3764                 xpt_free_ccb(free_ccb);
 3765                 sim->ccb_count--;
 3766         } else {
 3767                 SLIST_INSERT_HEAD(&sim->ccb_freeq, &free_ccb->ccb_h,
 3768                     xpt_links.sle);
 3769         }
 3770         if (sim->devq == NULL) {
 3771                 return;
 3772         }
 3773         sim->devq->alloc_openings++;
 3774         sim->devq->alloc_active--;
 3775         /* XXX Turn this into an inline function - xpt_run_device?? */
 3776         if ((device_is_alloc_queued(device) == 0)
 3777          && (device->drvq.entries > 0)) {
 3778                 xpt_schedule_dev_allocq(bus, device);
 3779         }
 3780         if (dev_allocq_is_runnable(sim->devq))
 3781                 xpt_run_dev_allocq(bus);
 3782 }
 3783 
 3784 /* Functions accessed by SIM drivers */
 3785 
 3786 static struct xpt_xport xport_default = {
 3787         .alloc_device = xpt_alloc_device_default,
 3788         .action = xpt_action_default,
 3789         .async = xpt_dev_async_default,
 3790 };
 3791 
 3792 /*
 3793  * A sim structure, listing the SIM entry points and instance
 3794  * identification info is passed to xpt_bus_register to hook the SIM
 3795  * into the CAM framework.  xpt_bus_register creates a cam_eb entry
 3796  * for this new bus and places it in the array of busses and assigns
 3797  * it a path_id.  The path_id may be influenced by "hard wiring"
 3798  * information specified by the user.  Once interrupt services are
 3799  * available, the bus will be probed.
 3800  */
 3801 int32_t
 3802 xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus)
 3803 {
 3804         struct cam_eb *new_bus;
 3805         struct cam_eb *old_bus;
 3806         struct ccb_pathinq cpi;
 3807         struct cam_path path;
 3808         cam_status status;
 3809 
 3810         mtx_assert(sim->mtx, MA_OWNED);
 3811 
 3812         sim->bus_id = bus;
 3813         new_bus = (struct cam_eb *)malloc(sizeof(*new_bus),
 3814                                           M_CAMXPT, M_NOWAIT);
 3815         if (new_bus == NULL) {
 3816                 /* Couldn't satisfy request */
 3817                 return (CAM_RESRC_UNAVAIL);
 3818         }
 3819 
 3820         if (strcmp(sim->sim_name, "xpt") != 0) {
 3821                 sim->path_id =
 3822                     xptpathid(sim->sim_name, sim->unit_number, sim->bus_id);
 3823         }
 3824 
 3825         TAILQ_INIT(&new_bus->et_entries);
 3826         new_bus->path_id = sim->path_id;
 3827         cam_sim_hold(sim);
 3828         new_bus->sim = sim;
 3829         timevalclear(&new_bus->last_reset);
 3830         new_bus->flags = 0;
 3831         new_bus->refcount = 1;  /* Held until a bus_deregister event */
 3832         new_bus->generation = 0;
 3833 
 3834         mtx_lock(&xsoftc.xpt_topo_lock);
 3835         old_bus = TAILQ_FIRST(&xsoftc.xpt_busses);
 3836         while (old_bus != NULL
 3837             && old_bus->path_id < new_bus->path_id)
 3838                 old_bus = TAILQ_NEXT(old_bus, links);
 3839         if (old_bus != NULL)
 3840                 TAILQ_INSERT_BEFORE(old_bus, new_bus, links);
 3841         else
 3842                 TAILQ_INSERT_TAIL(&xsoftc.xpt_busses, new_bus, links);
 3843         xsoftc.bus_generation++;
 3844         mtx_unlock(&xsoftc.xpt_topo_lock);
 3845 
 3846         /*
 3847          * Set a default transport so that a PATH_INQ can be issued to
 3848          * the SIM.  This will then allow for probing and attaching of
 3849          * a more appropriate transport.
 3850          */
 3851         new_bus->xport = &xport_default;
 3852 
 3853         bzero(&path, sizeof(path));
 3854         status = xpt_compile_path(&path, /*periph*/NULL, sim->path_id,
 3855                                   CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
 3856         if (status != CAM_REQ_CMP)
 3857                 printf("xpt_compile_path returned %d\n", status);
 3858 
 3859         xpt_setup_ccb(&cpi.ccb_h, &path, CAM_PRIORITY_NORMAL);
 3860         cpi.ccb_h.func_code = XPT_PATH_INQ;
 3861         xpt_action((union ccb *)&cpi);
 3862 
 3863         if (cpi.ccb_h.status == CAM_REQ_CMP) {
 3864                 switch (cpi.transport) {
 3865                 case XPORT_SPI:
 3866                 case XPORT_SAS:
 3867                 case XPORT_FC:
 3868                 case XPORT_USB:
 3869                 case XPORT_ISCSI:
 3870                 case XPORT_PPB:
 3871                         new_bus->xport = scsi_get_xport();
 3872                         break;
 3873                 case XPORT_ATA:
 3874                 case XPORT_SATA:
 3875                         new_bus->xport = ata_get_xport();
 3876                         break;
 3877                 default:
 3878                         new_bus->xport = &xport_default;
 3879                         break;
 3880                 }
 3881         }
 3882 
 3883         /* Notify interested parties */
 3884         if (sim->path_id != CAM_XPT_PATH_ID) {
 3885                 xpt_async(AC_PATH_REGISTERED, &path, &cpi);
 3886         }
 3887         xpt_release_path(&path);
 3888         return (CAM_SUCCESS);
 3889 }
 3890 
 3891 int32_t
 3892 xpt_bus_deregister(path_id_t pathid)
 3893 {
 3894         struct cam_path bus_path;
 3895         cam_status status;
 3896 
 3897         status = xpt_compile_path(&bus_path, NULL, pathid,
 3898                                   CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
 3899         if (status != CAM_REQ_CMP)
 3900                 return (status);
 3901 
 3902         xpt_async(AC_LOST_DEVICE, &bus_path, NULL);
 3903         xpt_async(AC_PATH_DEREGISTERED, &bus_path, NULL);
 3904 
 3905         /* Release the reference count held while registered. */
 3906         xpt_release_bus(bus_path.bus);
 3907         xpt_release_path(&bus_path);
 3908 
 3909         return (CAM_REQ_CMP);
 3910 }
 3911 
 3912 static path_id_t
 3913 xptnextfreepathid(void)
 3914 {
 3915         struct cam_eb *bus;
 3916         path_id_t pathid;
 3917         const char *strval;
 3918 
 3919         pathid = 0;
 3920         mtx_lock(&xsoftc.xpt_topo_lock);
 3921         bus = TAILQ_FIRST(&xsoftc.xpt_busses);
 3922 retry:
 3923         /* Find an unoccupied pathid */
 3924         while (bus != NULL && bus->path_id <= pathid) {
 3925                 if (bus->path_id == pathid)
 3926                         pathid++;
 3927                 bus = TAILQ_NEXT(bus, links);
 3928         }
 3929         mtx_unlock(&xsoftc.xpt_topo_lock);
 3930 
 3931         /*
 3932          * Ensure that this pathid is not reserved for
 3933          * a bus that may be registered in the future.
 3934          */
 3935         if (resource_string_value("scbus", pathid, "at", &strval) == 0) {
 3936                 ++pathid;
 3937                 /* Start the search over */
 3938                 mtx_lock(&xsoftc.xpt_topo_lock);
 3939                 goto retry;
 3940         }
 3941         return (pathid);
 3942 }
 3943 
 3944 static path_id_t
 3945 xptpathid(const char *sim_name, int sim_unit, int sim_bus)
 3946 {
 3947         path_id_t pathid;
 3948         int i, dunit, val;
 3949         char buf[32];
 3950         const char *dname;
 3951 
 3952         pathid = CAM_XPT_PATH_ID;
 3953         snprintf(buf, sizeof(buf), "%s%d", sim_name, sim_unit);
 3954         i = 0;
 3955         while ((resource_find_match(&i, &dname, &dunit, "at", buf)) == 0) {
 3956                 if (strcmp(dname, "scbus")) {
 3957                         /* Avoid a bit of foot shooting. */
 3958                         continue;
 3959                 }
 3960                 if (dunit < 0)          /* unwired?! */
 3961                         continue;
 3962                 if (resource_int_value("scbus", dunit, "bus", &val) == 0) {
 3963                         if (sim_bus == val) {
 3964                                 pathid = dunit;
 3965                                 break;
 3966                         }
 3967                 } else if (sim_bus == 0) {
 3968                         /* Unspecified matches bus 0 */
 3969                         pathid = dunit;
 3970                         break;
 3971                 } else {
 3972                         printf("Ambiguous scbus configuration for %s%d "
 3973                                "bus %d, cannot wire down.  The kernel "
 3974                                "config entry for scbus%d should "
 3975                                "specify a controller bus.\n"
 3976                                "Scbus will be assigned dynamically.\n",
 3977                                sim_name, sim_unit, sim_bus, dunit);
 3978                         break;
 3979                 }
 3980         }
 3981 
 3982         if (pathid == CAM_XPT_PATH_ID)
 3983                 pathid = xptnextfreepathid();
 3984         return (pathid);
 3985 }
 3986 
 3987 void
 3988 xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg)
 3989 {
 3990         struct cam_eb *bus;
 3991         struct cam_et *target, *next_target;
 3992         struct cam_ed *device, *next_device;
 3993 
 3994         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 3995 
 3996         CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_async\n"));
 3997 
 3998         /*
 3999          * Most async events come from a CAM interrupt context.  In
 4000          * a few cases, the error recovery code at the peripheral layer,
 4001          * which may run from our SWI or a process context, may signal
 4002          * deferred events with a call to xpt_async.
 4003          */
 4004 
 4005         bus = path->bus;
 4006 
 4007         if (async_code == AC_BUS_RESET) {
 4008                 /* Update our notion of when the last reset occurred */
 4009                 microtime(&bus->last_reset);
 4010         }
 4011 
 4012         for (target = TAILQ_FIRST(&bus->et_entries);
 4013              target != NULL;
 4014              target = next_target) {
 4015 
 4016                 next_target = TAILQ_NEXT(target, links);
 4017 
 4018                 if (path->target != target
 4019                  && path->target->target_id != CAM_TARGET_WILDCARD
 4020                  && target->target_id != CAM_TARGET_WILDCARD)
 4021                         continue;
 4022 
 4023                 if (async_code == AC_SENT_BDR) {
 4024                         /* Update our notion of when the last reset occurred */
 4025                         microtime(&path->target->last_reset);
 4026                 }
 4027 
 4028                 for (device = TAILQ_FIRST(&target->ed_entries);
 4029                      device != NULL;
 4030                      device = next_device) {
 4031 
 4032                         next_device = TAILQ_NEXT(device, links);
 4033 
 4034                         if (path->device != device
 4035                          && path->device->lun_id != CAM_LUN_WILDCARD
 4036                          && device->lun_id != CAM_LUN_WILDCARD)
 4037                                 continue;
 4038                         /*
 4039                          * The async callback could free the device.
 4040                          * If it is a broadcast async, it doesn't hold
 4041                          * device reference, so take our own reference.
 4042                          */
 4043                         xpt_acquire_device(device);
 4044                         (*(bus->xport->async))(async_code, bus,
 4045                                                target, device,
 4046                                                async_arg);
 4047 
 4048                         xpt_async_bcast(&device->asyncs, async_code,
 4049                                         path, async_arg);
 4050                         xpt_release_device(device);
 4051                 }
 4052         }
 4053 
 4054         /*
 4055          * If this wasn't a fully wildcarded async, tell all
 4056          * clients that want all async events.
 4057          */
 4058         if (bus != xpt_periph->path->bus)
 4059                 xpt_async_bcast(&xpt_periph->path->device->asyncs, async_code,
 4060                                 path, async_arg);
 4061 }
 4062 
 4063 static void
 4064 xpt_async_bcast(struct async_list *async_head,
 4065                 u_int32_t async_code,
 4066                 struct cam_path *path, void *async_arg)
 4067 {
 4068         struct async_node *cur_entry;
 4069 
 4070         cur_entry = SLIST_FIRST(async_head);
 4071         while (cur_entry != NULL) {
 4072                 struct async_node *next_entry;
 4073                 /*
 4074                  * Grab the next list entry before we call the current
 4075                  * entry's callback.  This is because the callback function
 4076                  * can delete its async callback entry.
 4077                  */
 4078                 next_entry = SLIST_NEXT(cur_entry, links);
 4079                 if ((cur_entry->event_enable & async_code) != 0)
 4080                         cur_entry->callback(cur_entry->callback_arg,
 4081                                             async_code, path,
 4082                                             async_arg);
 4083                 cur_entry = next_entry;
 4084         }
 4085 }
 4086 
 4087 static void
 4088 xpt_dev_async_default(u_int32_t async_code, struct cam_eb *bus,
 4089                       struct cam_et *target, struct cam_ed *device,
 4090                       void *async_arg)
 4091 {
 4092         printf("xpt_dev_async called\n");
 4093 }
 4094 
 4095 u_int32_t
 4096 xpt_freeze_devq(struct cam_path *path, u_int count)
 4097 {
 4098 
 4099         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 4100         path->device->ccbq.queue.qfrozen_cnt += count;
 4101         return (path->device->ccbq.queue.qfrozen_cnt);
 4102 }
 4103 
 4104 u_int32_t
 4105 xpt_freeze_simq(struct cam_sim *sim, u_int count)
 4106 {
 4107 
 4108         mtx_assert(sim->mtx, MA_OWNED);
 4109         sim->devq->send_queue.qfrozen_cnt += count;
 4110         return (sim->devq->send_queue.qfrozen_cnt);
 4111 }
 4112 
 4113 static void
 4114 xpt_release_devq_timeout(void *arg)
 4115 {
 4116         struct cam_ed *device;
 4117 
 4118         device = (struct cam_ed *)arg;
 4119 
 4120         xpt_release_devq_device(device, /*count*/1, /*run_queue*/TRUE);
 4121 }
 4122 
 4123 void
 4124 xpt_release_devq(struct cam_path *path, u_int count, int run_queue)
 4125 {
 4126         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 4127 
 4128         xpt_release_devq_device(path->device, count, run_queue);
 4129 }
 4130 
 4131 static void
 4132 xpt_release_devq_device(struct cam_ed *dev, u_int count, int run_queue)
 4133 {
 4134         int     rundevq;
 4135 
 4136         rundevq = 0;
 4137         if (dev->ccbq.queue.qfrozen_cnt > 0) {
 4138 
 4139                 count = (count > dev->ccbq.queue.qfrozen_cnt) ?
 4140                     dev->ccbq.queue.qfrozen_cnt : count;
 4141                 dev->ccbq.queue.qfrozen_cnt -= count;
 4142                 if (dev->ccbq.queue.qfrozen_cnt == 0) {
 4143 
 4144                         /*
 4145                          * No longer need to wait for a successful
 4146                          * command completion.
 4147                          */
 4148                         dev->flags &= ~CAM_DEV_REL_ON_COMPLETE;
 4149 
 4150                         /*
 4151                          * Remove any timeouts that might be scheduled
 4152                          * to release this queue.
 4153                          */
 4154                         if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) {
 4155                                 callout_stop(&dev->callout);
 4156                                 dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING;
 4157                         }
 4158 
 4159                         /*
 4160                          * Now that we are unfrozen schedule the
 4161                          * device so any pending transactions are
 4162                          * run.
 4163                          */
 4164                         if ((dev->ccbq.queue.entries > 0)
 4165                          && (xpt_schedule_dev_sendq(dev->target->bus, dev))
 4166                          && (run_queue != 0)) {
 4167                                 rundevq = 1;
 4168                         }
 4169                 }
 4170         }
 4171         if (rundevq != 0)
 4172                 xpt_run_dev_sendq(dev->target->bus);
 4173 }
 4174 
 4175 void
 4176 xpt_release_simq(struct cam_sim *sim, int run_queue)
 4177 {
 4178         struct  camq *sendq;
 4179 
 4180         mtx_assert(sim->mtx, MA_OWNED);
 4181 
 4182         sendq = &(sim->devq->send_queue);
 4183         if (sendq->qfrozen_cnt > 0) {
 4184 
 4185                 sendq->qfrozen_cnt--;
 4186                 if (sendq->qfrozen_cnt == 0) {
 4187                         /*
 4188                          * If there is a timeout scheduled to release this
 4189                          * sim queue, remove it.  The queue frozen count is
 4190                          * already at 0.
 4191                          */
 4192                         if ((sim->flags & CAM_SIM_REL_TIMEOUT_PENDING) != 0){
 4193                                 callout_stop(&sim->callout);
 4194                                 sim->flags &= ~CAM_SIM_REL_TIMEOUT_PENDING;
 4195                         }
 4196 
 4197                         if (run_queue) {
 4198                                 struct cam_eb *bus;
 4199 
 4200                                 /*
 4201                                  * Now that we are unfrozen run the send queue.
 4202                                  */
 4203                                 bus = xpt_find_bus(sim->path_id);
 4204                                 xpt_run_dev_sendq(bus);
 4205                                 xpt_release_bus(bus);
 4206                         }
 4207                 }
 4208         }
 4209 }
 4210 
 4211 /*
 4212  * XXX Appears to be unused.
 4213  */
 4214 static void
 4215 xpt_release_simq_timeout(void *arg)
 4216 {
 4217         struct cam_sim *sim;
 4218 
 4219         sim = (struct cam_sim *)arg;
 4220         xpt_release_simq(sim, /* run_queue */ TRUE);
 4221 }
 4222 
 4223 void
 4224 xpt_done(union ccb *done_ccb)
 4225 {
 4226         struct cam_sim *sim;
 4227         int     first;
 4228 
 4229         CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_done\n"));
 4230         if ((done_ccb->ccb_h.func_code & XPT_FC_QUEUED) != 0) {
 4231                 /*
 4232                  * Queue up the request for handling by our SWI handler
 4233                  * any of the "non-immediate" type of ccbs.
 4234                  */
 4235                 sim = done_ccb->ccb_h.path->bus->sim;
 4236                 TAILQ_INSERT_TAIL(&sim->sim_doneq, &done_ccb->ccb_h,
 4237                     sim_links.tqe);
 4238                 done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
 4239                 if ((sim->flags & CAM_SIM_ON_DONEQ) == 0) {
 4240                         mtx_lock(&cam_simq_lock);
 4241                         first = TAILQ_EMPTY(&cam_simq);
 4242                         TAILQ_INSERT_TAIL(&cam_simq, sim, links);
 4243                         mtx_unlock(&cam_simq_lock);
 4244                         sim->flags |= CAM_SIM_ON_DONEQ;
 4245                         if (first)
 4246                                 swi_sched(cambio_ih, 0);
 4247                 }
 4248         }
 4249 }
 4250 
 4251 union ccb *
 4252 xpt_alloc_ccb()
 4253 {
 4254         union ccb *new_ccb;
 4255 
 4256         new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_ZERO|M_WAITOK);
 4257         return (new_ccb);
 4258 }
 4259 
 4260 union ccb *
 4261 xpt_alloc_ccb_nowait()
 4262 {
 4263         union ccb *new_ccb;
 4264 
 4265         new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_ZERO|M_NOWAIT);
 4266         return (new_ccb);
 4267 }
 4268 
 4269 void
 4270 xpt_free_ccb(union ccb *free_ccb)
 4271 {
 4272         free(free_ccb, M_CAMXPT);
 4273 }
 4274 
 4275 
 4276 
 4277 /* Private XPT functions */
 4278 
 4279 /*
 4280  * Get a CAM control block for the caller. Charge the structure to the device
 4281  * referenced by the path.  If the this device has no 'credits' then the
 4282  * device already has the maximum number of outstanding operations under way
 4283  * and we return NULL. If we don't have sufficient resources to allocate more
 4284  * ccbs, we also return NULL.
 4285  */
 4286 static union ccb *
 4287 xpt_get_ccb(struct cam_ed *device)
 4288 {
 4289         union ccb *new_ccb;
 4290         struct cam_sim *sim;
 4291 
 4292         sim = device->sim;
 4293         if ((new_ccb = (union ccb *)SLIST_FIRST(&sim->ccb_freeq)) == NULL) {
 4294                 new_ccb = xpt_alloc_ccb_nowait();
 4295                 if (new_ccb == NULL) {
 4296                         return (NULL);
 4297                 }
 4298                 if ((sim->flags & CAM_SIM_MPSAFE) == 0)
 4299                         callout_handle_init(&new_ccb->ccb_h.timeout_ch);
 4300                 SLIST_INSERT_HEAD(&sim->ccb_freeq, &new_ccb->ccb_h,
 4301                                   xpt_links.sle);
 4302                 sim->ccb_count++;
 4303         }
 4304         cam_ccbq_take_opening(&device->ccbq);
 4305         SLIST_REMOVE_HEAD(&sim->ccb_freeq, xpt_links.sle);
 4306         return (new_ccb);
 4307 }
 4308 
 4309 static void
 4310 xpt_release_bus(struct cam_eb *bus)
 4311 {
 4312 
 4313         if ((--bus->refcount == 0)
 4314          && (TAILQ_FIRST(&bus->et_entries) == NULL)) {
 4315                 mtx_lock(&xsoftc.xpt_topo_lock);
 4316                 TAILQ_REMOVE(&xsoftc.xpt_busses, bus, links);
 4317                 xsoftc.bus_generation++;
 4318                 mtx_unlock(&xsoftc.xpt_topo_lock);
 4319                 cam_sim_release(bus->sim);
 4320                 free(bus, M_CAMXPT);
 4321         }
 4322 }
 4323 
 4324 static struct cam_et *
 4325 xpt_alloc_target(struct cam_eb *bus, target_id_t target_id)
 4326 {
 4327         struct cam_et *target;
 4328 
 4329         target = (struct cam_et *)malloc(sizeof(*target), M_CAMXPT, M_NOWAIT);
 4330         if (target != NULL) {
 4331                 struct cam_et *cur_target;
 4332 
 4333                 TAILQ_INIT(&target->ed_entries);
 4334                 target->bus = bus;
 4335                 target->target_id = target_id;
 4336                 target->refcount = 1;
 4337                 target->generation = 0;
 4338                 timevalclear(&target->last_reset);
 4339                 /*
 4340                  * Hold a reference to our parent bus so it
 4341                  * will not go away before we do.
 4342                  */
 4343                 bus->refcount++;
 4344 
 4345                 /* Insertion sort into our bus's target list */
 4346                 cur_target = TAILQ_FIRST(&bus->et_entries);
 4347                 while (cur_target != NULL && cur_target->target_id < target_id)
 4348                         cur_target = TAILQ_NEXT(cur_target, links);
 4349 
 4350                 if (cur_target != NULL) {
 4351                         TAILQ_INSERT_BEFORE(cur_target, target, links);
 4352                 } else {
 4353                         TAILQ_INSERT_TAIL(&bus->et_entries, target, links);
 4354                 }
 4355                 bus->generation++;
 4356         }
 4357         return (target);
 4358 }
 4359 
 4360 static void
 4361 xpt_release_target(struct cam_et *target)
 4362 {
 4363 
 4364         if ((--target->refcount == 0)
 4365          && (TAILQ_FIRST(&target->ed_entries) == NULL)) {
 4366                 TAILQ_REMOVE(&target->bus->et_entries, target, links);
 4367                 target->bus->generation++;
 4368                 xpt_release_bus(target->bus);
 4369                 free(target, M_CAMXPT);
 4370         }
 4371 }
 4372 
 4373 static struct cam_ed *
 4374 xpt_alloc_device_default(struct cam_eb *bus, struct cam_et *target,
 4375                          lun_id_t lun_id)
 4376 {
 4377         struct cam_ed *device, *cur_device;
 4378 
 4379         device = xpt_alloc_device(bus, target, lun_id);
 4380         if (device == NULL)
 4381                 return (NULL);
 4382 
 4383         device->mintags = 1;
 4384         device->maxtags = 1;
 4385         bus->sim->max_ccbs = device->ccbq.devq_openings;
 4386         cur_device = TAILQ_FIRST(&target->ed_entries);
 4387         while (cur_device != NULL && cur_device->lun_id < lun_id)
 4388                 cur_device = TAILQ_NEXT(cur_device, links);
 4389         if (cur_device != NULL) {
 4390                 TAILQ_INSERT_BEFORE(cur_device, device, links);
 4391         } else {
 4392                 TAILQ_INSERT_TAIL(&target->ed_entries, device, links);
 4393         }
 4394         target->generation++;
 4395 
 4396         return (device);
 4397 }
 4398 
 4399 struct cam_ed *
 4400 xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
 4401 {
 4402         struct     cam_ed *device;
 4403         struct     cam_devq *devq;
 4404         cam_status status;
 4405 
 4406         /* Make space for us in the device queue on our bus */
 4407         devq = bus->sim->devq;
 4408         status = cam_devq_resize(devq, devq->alloc_queue.array_size + 1);
 4409 
 4410         if (status != CAM_REQ_CMP) {
 4411                 device = NULL;
 4412         } else {
 4413                 device = (struct cam_ed *)malloc(sizeof(*device),
 4414                                                  M_CAMXPT, M_NOWAIT);
 4415         }
 4416 
 4417         if (device != NULL) {
 4418                 cam_init_pinfo(&device->alloc_ccb_entry.pinfo);
 4419                 device->alloc_ccb_entry.device = device;
 4420                 cam_init_pinfo(&device->send_ccb_entry.pinfo);
 4421                 device->send_ccb_entry.device = device;
 4422                 device->target = target;
 4423                 device->lun_id = lun_id;
 4424                 device->sim = bus->sim;
 4425                 /* Initialize our queues */
 4426                 if (camq_init(&device->drvq, 0) != 0) {
 4427                         free(device, M_CAMXPT);
 4428                         return (NULL);
 4429                 }
 4430                 if (cam_ccbq_init(&device->ccbq,
 4431                                   bus->sim->max_dev_openings) != 0) {
 4432                         camq_fini(&device->drvq);
 4433                         free(device, M_CAMXPT);
 4434                         return (NULL);
 4435                 }
 4436                 SLIST_INIT(&device->asyncs);
 4437                 SLIST_INIT(&device->periphs);
 4438                 device->generation = 0;
 4439                 device->owner = NULL;
 4440                 device->flags = CAM_DEV_UNCONFIGURED;
 4441                 device->tag_delay_count = 0;
 4442                 device->tag_saved_openings = 0;
 4443                 device->refcount = 1;
 4444                 callout_init_mtx(&device->callout, bus->sim->mtx, 0);
 4445 
 4446                 /*
 4447                  * Hold a reference to our parent target so it
 4448                  * will not go away before we do.
 4449                  */
 4450                 target->refcount++;
 4451 
 4452         }
 4453         return (device);
 4454 }
 4455 
 4456 void
 4457 xpt_acquire_device(struct cam_ed *device)
 4458 {
 4459 
 4460         device->refcount++;
 4461 }
 4462 
 4463 void
 4464 xpt_release_device(struct cam_ed *device)
 4465 {
 4466 
 4467         if (--device->refcount == 0) {
 4468                 struct cam_devq *devq;
 4469 
 4470                 if (device->alloc_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX
 4471                  || device->send_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX)
 4472                         panic("Removing device while still queued for ccbs");
 4473 
 4474                 if ((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0)
 4475                                 callout_stop(&device->callout);
 4476 
 4477                 TAILQ_REMOVE(&device->target->ed_entries, device,links);
 4478                 device->target->generation++;
 4479                 device->target->bus->sim->max_ccbs -= device->ccbq.devq_openings;
 4480                 /* Release our slot in the devq */
 4481                 devq = device->target->bus->sim->devq;
 4482                 cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
 4483                 camq_fini(&device->drvq);
 4484                 cam_ccbq_fini(&device->ccbq);
 4485                 xpt_release_target(device->target);
 4486                 free(device, M_CAMXPT);
 4487         }
 4488 }
 4489 
 4490 u_int32_t
 4491 xpt_dev_ccbq_resize(struct cam_path *path, int newopenings)
 4492 {
 4493         int     diff;
 4494         int     result;
 4495         struct  cam_ed *dev;
 4496 
 4497         dev = path->device;
 4498 
 4499         diff = newopenings - (dev->ccbq.dev_active + dev->ccbq.dev_openings);
 4500         result = cam_ccbq_resize(&dev->ccbq, newopenings);
 4501         if (result == CAM_REQ_CMP && (diff < 0)) {
 4502                 dev->flags |= CAM_DEV_RESIZE_QUEUE_NEEDED;
 4503         }
 4504         if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
 4505          || (dev->inq_flags & SID_CmdQue) != 0)
 4506                 dev->tag_saved_openings = newopenings;
 4507         /* Adjust the global limit */
 4508         dev->sim->max_ccbs += diff;
 4509         return (result);
 4510 }
 4511 
 4512 static struct cam_eb *
 4513 xpt_find_bus(path_id_t path_id)
 4514 {
 4515         struct cam_eb *bus;
 4516 
 4517         mtx_lock(&xsoftc.xpt_topo_lock);
 4518         for (bus = TAILQ_FIRST(&xsoftc.xpt_busses);
 4519              bus != NULL;
 4520              bus = TAILQ_NEXT(bus, links)) {
 4521                 if (bus->path_id == path_id) {
 4522                         bus->refcount++;
 4523                         break;
 4524                 }
 4525         }
 4526         mtx_unlock(&xsoftc.xpt_topo_lock);
 4527         return (bus);
 4528 }
 4529 
 4530 static struct cam_et *
 4531 xpt_find_target(struct cam_eb *bus, target_id_t target_id)
 4532 {
 4533         struct cam_et *target;
 4534 
 4535         for (target = TAILQ_FIRST(&bus->et_entries);
 4536              target != NULL;
 4537              target = TAILQ_NEXT(target, links)) {
 4538                 if (target->target_id == target_id) {
 4539                         target->refcount++;
 4540                         break;
 4541                 }
 4542         }
 4543         return (target);
 4544 }
 4545 
 4546 static struct cam_ed *
 4547 xpt_find_device(struct cam_et *target, lun_id_t lun_id)
 4548 {
 4549         struct cam_ed *device;
 4550 
 4551         for (device = TAILQ_FIRST(&target->ed_entries);
 4552              device != NULL;
 4553              device = TAILQ_NEXT(device, links)) {
 4554                 if (device->lun_id == lun_id) {
 4555                         device->refcount++;
 4556                         break;
 4557                 }
 4558         }
 4559         return (device);
 4560 }
 4561 
 4562 void
 4563 xpt_start_tags(struct cam_path *path)
 4564 {
 4565         struct ccb_relsim crs;
 4566         struct cam_ed *device;
 4567         struct cam_sim *sim;
 4568         int    newopenings;
 4569 
 4570         device = path->device;
 4571         sim = path->bus->sim;
 4572         device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
 4573         xpt_freeze_devq(path, /*count*/1);
 4574         device->inq_flags |= SID_CmdQue;
 4575         if (device->tag_saved_openings != 0)
 4576                 newopenings = device->tag_saved_openings;
 4577         else
 4578                 newopenings = min(device->maxtags,
 4579                                   sim->max_tagged_dev_openings);
 4580         xpt_dev_ccbq_resize(path, newopenings);
 4581         xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NORMAL);
 4582         crs.ccb_h.func_code = XPT_REL_SIMQ;
 4583         crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
 4584         crs.openings
 4585             = crs.release_timeout
 4586             = crs.qfrozen_cnt
 4587             = 0;
 4588         xpt_action((union ccb *)&crs);
 4589 }
 4590 
 4591 void
 4592 xpt_stop_tags(struct cam_path *path)
 4593 {
 4594         struct ccb_relsim crs;
 4595         struct cam_ed *device;
 4596         struct cam_sim *sim;
 4597 
 4598         device = path->device;
 4599         sim = path->bus->sim;
 4600         device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
 4601         device->tag_delay_count = 0;
 4602         xpt_freeze_devq(path, /*count*/1);
 4603         device->inq_flags &= ~SID_CmdQue;
 4604         xpt_dev_ccbq_resize(path, sim->max_dev_openings);
 4605         xpt_setup_ccb(&crs.ccb_h, path, CAM_PRIORITY_NORMAL);
 4606         crs.ccb_h.func_code = XPT_REL_SIMQ;
 4607         crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
 4608         crs.openings
 4609             = crs.release_timeout
 4610             = crs.qfrozen_cnt
 4611             = 0;
 4612         xpt_action((union ccb *)&crs);
 4613 }
 4614 
 4615 static int busses_to_config;
 4616 static int busses_to_reset;
 4617 
 4618 static int
 4619 xptconfigbuscountfunc(struct cam_eb *bus, void *arg)
 4620 {
 4621 
 4622         mtx_assert(bus->sim->mtx, MA_OWNED);
 4623 
 4624         if (bus->path_id != CAM_XPT_PATH_ID) {
 4625                 struct cam_path path;
 4626                 struct ccb_pathinq cpi;
 4627                 int can_negotiate;
 4628 
 4629                 busses_to_config++;
 4630                 xpt_compile_path(&path, NULL, bus->path_id,
 4631                                  CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
 4632                 xpt_setup_ccb(&cpi.ccb_h, &path, CAM_PRIORITY_NORMAL);
 4633                 cpi.ccb_h.func_code = XPT_PATH_INQ;
 4634                 xpt_action((union ccb *)&cpi);
 4635                 can_negotiate = cpi.hba_inquiry;
 4636                 can_negotiate &= (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE);
 4637                 if ((cpi.hba_misc & PIM_NOBUSRESET) == 0
 4638                  && can_negotiate)
 4639                         busses_to_reset++;
 4640                 xpt_release_path(&path);
 4641         }
 4642 
 4643         return(1);
 4644 }
 4645 
 4646 static int
 4647 xptconfigfunc(struct cam_eb *bus, void *arg)
 4648 {
 4649         struct  cam_path *path;
 4650         union   ccb *work_ccb;
 4651 
 4652         mtx_assert(bus->sim->mtx, MA_OWNED);
 4653 
 4654         if (bus->path_id != CAM_XPT_PATH_ID) {
 4655                 cam_status status;
 4656                 int can_negotiate;
 4657 
 4658                 work_ccb = xpt_alloc_ccb_nowait();
 4659                 if (work_ccb == NULL) {
 4660                         busses_to_config--;
 4661                         xpt_finishconfig(xpt_periph, NULL);
 4662                         return(0);
 4663                 }
 4664                 if ((status = xpt_create_path(&path, xpt_periph, bus->path_id,
 4665                                               CAM_TARGET_WILDCARD,
 4666                                               CAM_LUN_WILDCARD)) !=CAM_REQ_CMP){
 4667                         printf("xptconfigfunc: xpt_create_path failed with "
 4668                                "status %#x for scbus%d\n", status, bus->path_id);
 4669                         printf("xptconfigfunc: halting bus configuration\n");
 4670                         xpt_free_ccb(work_ccb);
 4671                         busses_to_config--;
 4672                         xpt_finishconfig(xpt_periph, NULL);
 4673                         return(0);
 4674                 }
 4675                 xpt_setup_ccb(&work_ccb->ccb_h, path, CAM_PRIORITY_NORMAL);
 4676                 work_ccb->ccb_h.func_code = XPT_PATH_INQ;
 4677                 xpt_action(work_ccb);
 4678                 if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
 4679                         printf("xptconfigfunc: CPI failed on scbus%d "
 4680                                "with status %d\n", bus->path_id,
 4681                                work_ccb->ccb_h.status);
 4682                         xpt_finishconfig(xpt_periph, work_ccb);
 4683                         return(1);
 4684                 }
 4685 
 4686                 can_negotiate = work_ccb->cpi.hba_inquiry;
 4687                 can_negotiate &= (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE);
 4688                 if ((work_ccb->cpi.hba_misc & PIM_NOBUSRESET) == 0
 4689                  && (can_negotiate != 0)) {
 4690                         xpt_setup_ccb(&work_ccb->ccb_h, path, CAM_PRIORITY_NORMAL);
 4691                         work_ccb->ccb_h.func_code = XPT_RESET_BUS;
 4692                         work_ccb->ccb_h.cbfcnp = NULL;
 4693                         CAM_DEBUG(path, CAM_DEBUG_SUBTRACE,
 4694                                   ("Resetting Bus\n"));
 4695                         xpt_action(work_ccb);
 4696                         xpt_finishconfig(xpt_periph, work_ccb);
 4697                 } else {
 4698                         /* Act as though we performed a successful BUS RESET */
 4699                         work_ccb->ccb_h.func_code = XPT_RESET_BUS;
 4700                         xpt_finishconfig(xpt_periph, work_ccb);
 4701                 }
 4702         }
 4703 
 4704         return(1);
 4705 }
 4706 
 4707 static void
 4708 xpt_config(void *arg)
 4709 {
 4710         struct  periph_driver **p_drv;
 4711         int     i;
 4712 
 4713         /*
 4714          * Now that interrupts are enabled, go find our devices
 4715          */
 4716 
 4717 #ifdef CAMDEBUG
 4718         /* Setup debugging flags and path */
 4719 #ifdef CAM_DEBUG_FLAGS
 4720         cam_dflags = CAM_DEBUG_FLAGS;
 4721 #else /* !CAM_DEBUG_FLAGS */
 4722         cam_dflags = CAM_DEBUG_NONE;
 4723 #endif /* CAM_DEBUG_FLAGS */
 4724 #ifdef CAM_DEBUG_BUS
 4725         if (cam_dflags != CAM_DEBUG_NONE) {
 4726                 /*
 4727                  * Locking is specifically omitted here.  No SIMs have
 4728                  * registered yet, so xpt_create_path will only be searching
 4729                  * empty lists of targets and devices.
 4730                  */
 4731                 if (xpt_create_path(&cam_dpath, xpt_periph,
 4732                                     CAM_DEBUG_BUS, CAM_DEBUG_TARGET,
 4733                                     CAM_DEBUG_LUN) != CAM_REQ_CMP) {
 4734                         printf("xpt_config: xpt_create_path() failed for debug"
 4735                                " target %d:%d:%d, debugging disabled\n",
 4736                                CAM_DEBUG_BUS, CAM_DEBUG_TARGET, CAM_DEBUG_LUN);
 4737                         cam_dflags = CAM_DEBUG_NONE;
 4738                 }
 4739         } else
 4740                 cam_dpath = NULL;
 4741 #else /* !CAM_DEBUG_BUS */
 4742         cam_dpath = NULL;
 4743 #endif /* CAM_DEBUG_BUS */
 4744 #endif /* CAMDEBUG */
 4745 
 4746         /* Register early peripheral drivers */
 4747         /* XXX This will have to change when we have loadable modules */
 4748         p_drv = periph_drivers;
 4749         for (i = 0; p_drv[i] != NULL; i++) {
 4750                 if ((p_drv[i]->flags & CAM_PERIPH_DRV_EARLY) != 0)
 4751                         (*p_drv[i]->init)();
 4752         }
 4753         /*
 4754          * Scan all installed busses.
 4755          */
 4756         xpt_for_all_busses(xptconfigbuscountfunc, NULL);
 4757 
 4758         if (busses_to_config == 0) {
 4759                 /* Call manually because we don't have any busses */
 4760                 xpt_finishconfig(xpt_periph, NULL);
 4761         } else  {
 4762                 if (busses_to_reset > 0 && scsi_delay >= 2000) {
 4763                         printf("Waiting %d seconds for SCSI "
 4764                                "devices to settle\n", scsi_delay/1000);
 4765                 }
 4766                 xpt_for_all_busses(xptconfigfunc, NULL);
 4767         }
 4768 }
 4769 
 4770 /*
 4771  * If the given device only has one peripheral attached to it, and if that
 4772  * peripheral is the passthrough driver, announce it.  This insures that the
 4773  * user sees some sort of announcement for every peripheral in their system.
 4774  */
 4775 static int
 4776 xptpassannouncefunc(struct cam_ed *device, void *arg)
 4777 {
 4778         struct cam_periph *periph;
 4779         int i;
 4780 
 4781         for (periph = SLIST_FIRST(&device->periphs), i = 0; periph != NULL;
 4782              periph = SLIST_NEXT(periph, periph_links), i++);
 4783 
 4784         periph = SLIST_FIRST(&device->periphs);
 4785         if ((i == 1)
 4786          && (strncmp(periph->periph_name, "pass", 4) == 0))
 4787                 xpt_announce_periph(periph, NULL);
 4788 
 4789         return(1);
 4790 }
 4791 
 4792 static void
 4793 xpt_finishconfig_task(void *context, int pending)
 4794 {
 4795         struct  periph_driver **p_drv;
 4796         int     i;
 4797 
 4798         if (busses_to_config == 0) {
 4799                 /* Register all the peripheral drivers */
 4800                 /* XXX This will have to change when we have loadable modules */
 4801                 p_drv = periph_drivers;
 4802                 for (i = 0; p_drv[i] != NULL; i++) {
 4803                         if ((p_drv[i]->flags & CAM_PERIPH_DRV_EARLY) == 0)
 4804                                 (*p_drv[i]->init)();
 4805                 }
 4806 
 4807                 /*
 4808                  * Check for devices with no "standard" peripheral driver
 4809                  * attached.  For any devices like that, announce the
 4810                  * passthrough driver so the user will see something.
 4811                  */
 4812                 xpt_for_all_devices(xptpassannouncefunc, NULL);
 4813 
 4814                 /* Release our hook so that the boot can continue. */
 4815                 config_intrhook_disestablish(xsoftc.xpt_config_hook);
 4816                 free(xsoftc.xpt_config_hook, M_CAMXPT);
 4817                 xsoftc.xpt_config_hook = NULL;
 4818         }
 4819 
 4820         free(context, M_CAMXPT);
 4821 }
 4822 
 4823 static void
 4824 xpt_finishconfig(struct cam_periph *periph, union ccb *done_ccb)
 4825 {
 4826         struct  xpt_task *task;
 4827 
 4828         if (done_ccb != NULL) {
 4829                 CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE,
 4830                           ("xpt_finishconfig\n"));
 4831                 switch(done_ccb->ccb_h.func_code) {
 4832                 case XPT_RESET_BUS:
 4833                         if (done_ccb->ccb_h.status == CAM_REQ_CMP) {
 4834                                 done_ccb->ccb_h.func_code = XPT_SCAN_BUS;
 4835                                 done_ccb->ccb_h.cbfcnp = xpt_finishconfig;
 4836                                 done_ccb->crcn.flags = 0;
 4837                                 xpt_action(done_ccb);
 4838                                 return;
 4839                         }
 4840                         /* FALLTHROUGH */
 4841                 case XPT_SCAN_BUS:
 4842                 default:
 4843                         xpt_free_path(done_ccb->ccb_h.path);
 4844                         busses_to_config--;
 4845                         break;
 4846                 }
 4847         }
 4848 
 4849         if (busses_to_config == 0) {
 4850                 task = malloc(sizeof(struct xpt_task), M_CAMXPT, M_NOWAIT);
 4851                 if (task != NULL) {
 4852                         TASK_INIT(&task->task, 0, xpt_finishconfig_task, task);
 4853                         taskqueue_enqueue(taskqueue_thread, &task->task);
 4854                 }
 4855         }
 4856 
 4857         if (done_ccb != NULL)
 4858                 xpt_free_ccb(done_ccb);
 4859 }
 4860 
 4861 cam_status
 4862 xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg,
 4863                    struct cam_path *path)
 4864 {
 4865         struct ccb_setasync csa;
 4866         cam_status status;
 4867         int xptpath = 0;
 4868 
 4869         if (path == NULL) {
 4870                 mtx_lock(&xsoftc.xpt_lock);
 4871                 status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID,
 4872                                          CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
 4873                 if (status != CAM_REQ_CMP) {
 4874                         mtx_unlock(&xsoftc.xpt_lock);
 4875                         return (status);
 4876                 }
 4877                 xptpath = 1;
 4878         }
 4879 
 4880         xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
 4881         csa.ccb_h.func_code = XPT_SASYNC_CB;
 4882         csa.event_enable = event;
 4883         csa.callback = cbfunc;
 4884         csa.callback_arg = cbarg;
 4885         xpt_action((union ccb *)&csa);
 4886         status = csa.ccb_h.status;
 4887         if (xptpath) {
 4888                 xpt_free_path(path);
 4889                 mtx_unlock(&xsoftc.xpt_lock);
 4890         }
 4891         return (status);
 4892 }
 4893 
 4894 static void
 4895 xptaction(struct cam_sim *sim, union ccb *work_ccb)
 4896 {
 4897         CAM_DEBUG(work_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xptaction\n"));
 4898 
 4899         switch (work_ccb->ccb_h.func_code) {
 4900         /* Common cases first */
 4901         case XPT_PATH_INQ:              /* Path routing inquiry */
 4902         {
 4903                 struct ccb_pathinq *cpi;
 4904 
 4905                 cpi = &work_ccb->cpi;
 4906                 cpi->version_num = 1; /* XXX??? */
 4907                 cpi->hba_inquiry = 0;
 4908                 cpi->target_sprt = 0;
 4909                 cpi->hba_misc = 0;
 4910                 cpi->hba_eng_cnt = 0;
 4911                 cpi->max_target = 0;
 4912                 cpi->max_lun = 0;
 4913                 cpi->initiator_id = 0;
 4914                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 4915                 strncpy(cpi->hba_vid, "", HBA_IDLEN);
 4916                 strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
 4917                 cpi->unit_number = sim->unit_number;
 4918                 cpi->bus_id = sim->bus_id;
 4919                 cpi->base_transfer_speed = 0;
 4920                 cpi->protocol = PROTO_UNSPECIFIED;
 4921                 cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
 4922                 cpi->transport = XPORT_UNSPECIFIED;
 4923                 cpi->transport_version = XPORT_VERSION_UNSPECIFIED;
 4924                 cpi->ccb_h.status = CAM_REQ_CMP;
 4925                 xpt_done(work_ccb);
 4926                 break;
 4927         }
 4928         default:
 4929                 work_ccb->ccb_h.status = CAM_REQ_INVALID;
 4930                 xpt_done(work_ccb);
 4931                 break;
 4932         }
 4933 }
 4934 
 4935 /*
 4936  * The xpt as a "controller" has no interrupt sources, so polling
 4937  * is a no-op.
 4938  */
 4939 static void
 4940 xptpoll(struct cam_sim *sim)
 4941 {
 4942 }
 4943 
 4944 void
 4945 xpt_lock_buses(void)
 4946 {
 4947         mtx_lock(&xsoftc.xpt_topo_lock);
 4948 }
 4949 
 4950 void
 4951 xpt_unlock_buses(void)
 4952 {
 4953         mtx_unlock(&xsoftc.xpt_topo_lock);
 4954 }
 4955 
 4956 static void
 4957 camisr(void *dummy)
 4958 {
 4959         cam_simq_t queue;
 4960         struct cam_sim *sim;
 4961 
 4962         mtx_lock(&cam_simq_lock);
 4963         TAILQ_INIT(&queue);
 4964         while (!TAILQ_EMPTY(&cam_simq)) {
 4965                 TAILQ_CONCAT(&queue, &cam_simq, links);
 4966                 mtx_unlock(&cam_simq_lock);
 4967 
 4968                 while ((sim = TAILQ_FIRST(&queue)) != NULL) {
 4969                         TAILQ_REMOVE(&queue, sim, links);
 4970                         CAM_SIM_LOCK(sim);
 4971                         sim->flags &= ~CAM_SIM_ON_DONEQ;
 4972                         camisr_runqueue(&sim->sim_doneq);
 4973                         CAM_SIM_UNLOCK(sim);
 4974                 }
 4975                 mtx_lock(&cam_simq_lock);
 4976         }
 4977         mtx_unlock(&cam_simq_lock);
 4978 }
 4979 
 4980 static void
 4981 camisr_runqueue(void *V_queue)
 4982 {
 4983         cam_isrq_t *queue = V_queue;
 4984         struct  ccb_hdr *ccb_h;
 4985 
 4986         while ((ccb_h = TAILQ_FIRST(queue)) != NULL) {
 4987                 int     runq;
 4988 
 4989                 TAILQ_REMOVE(queue, ccb_h, sim_links.tqe);
 4990                 ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
 4991 
 4992                 CAM_DEBUG(ccb_h->path, CAM_DEBUG_TRACE,
 4993                           ("camisr\n"));
 4994 
 4995                 runq = FALSE;
 4996 
 4997                 if (ccb_h->flags & CAM_HIGH_POWER) {
 4998                         struct highpowerlist    *hphead;
 4999                         union ccb               *send_ccb;
 5000 
 5001                         mtx_lock(&xsoftc.xpt_lock);
 5002                         hphead = &xsoftc.highpowerq;
 5003 
 5004                         send_ccb = (union ccb *)STAILQ_FIRST(hphead);
 5005 
 5006                         /*
 5007                          * Increment the count since this command is done.
 5008                          */
 5009                         xsoftc.num_highpower++;
 5010 
 5011                         /*
 5012                          * Any high powered commands queued up?
 5013                          */
 5014                         if (send_ccb != NULL) {
 5015 
 5016                                 STAILQ_REMOVE_HEAD(hphead, xpt_links.stqe);
 5017                                 mtx_unlock(&xsoftc.xpt_lock);
 5018 
 5019                                 xpt_release_devq(send_ccb->ccb_h.path,
 5020                                                  /*count*/1, /*runqueue*/TRUE);
 5021                         } else
 5022                                 mtx_unlock(&xsoftc.xpt_lock);
 5023                 }
 5024 
 5025                 if ((ccb_h->func_code & XPT_FC_USER_CCB) == 0) {
 5026                         struct cam_ed *dev;
 5027 
 5028                         dev = ccb_h->path->device;
 5029 
 5030                         cam_ccbq_ccb_done(&dev->ccbq, (union ccb *)ccb_h);
 5031                         ccb_h->path->bus->sim->devq->send_active--;
 5032                         ccb_h->path->bus->sim->devq->send_openings++;
 5033 
 5034                         if (((dev->flags & CAM_DEV_REL_ON_COMPLETE) != 0
 5035                           && (ccb_h->status&CAM_STATUS_MASK) != CAM_REQUEUE_REQ)
 5036                          || ((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0
 5037                           && (dev->ccbq.dev_active == 0))) {
 5038 
 5039                                 xpt_release_devq(ccb_h->path, /*count*/1,
 5040                                                  /*run_queue*/TRUE);
 5041                         }
 5042 
 5043                         if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
 5044                          && (--dev->tag_delay_count == 0))
 5045                                 xpt_start_tags(ccb_h->path);
 5046 
 5047                         if ((dev->ccbq.queue.entries > 0)
 5048                          && (dev->ccbq.queue.qfrozen_cnt == 0)
 5049                          && (device_is_send_queued(dev) == 0)) {
 5050                                 runq = xpt_schedule_dev_sendq(ccb_h->path->bus,
 5051                                                               dev);
 5052                         }
 5053                 }
 5054 
 5055                 if (ccb_h->status & CAM_RELEASE_SIMQ) {
 5056                         xpt_release_simq(ccb_h->path->bus->sim,
 5057                                          /*run_queue*/TRUE);
 5058                         ccb_h->status &= ~CAM_RELEASE_SIMQ;
 5059                         runq = FALSE;
 5060                 }
 5061 
 5062                 if ((ccb_h->flags & CAM_DEV_QFRZDIS)
 5063                  && (ccb_h->status & CAM_DEV_QFRZN)) {
 5064                         xpt_release_devq(ccb_h->path, /*count*/1,
 5065                                          /*run_queue*/TRUE);
 5066                         ccb_h->status &= ~CAM_DEV_QFRZN;
 5067                 } else if (runq) {
 5068                         xpt_run_dev_sendq(ccb_h->path->bus);
 5069                 }
 5070 
 5071                 /* Call the peripheral driver's callback */
 5072                 (*ccb_h->cbfcnp)(ccb_h->path->periph, (union ccb *)ccb_h);
 5073         }
 5074 }
 5075 

Cache object: e181f05c5ea244c7e2e0a9e79fe2fc9d


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