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

Cache object: bc0018dabebfc0e44898d2884d6f7a18


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