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


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

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

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

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

Cache object: 9ab33605461fb601be9f8f026e02a3a7


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