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: releng/7.3/sys/cam/cam_xpt.c 197213 2009-09-15 02:23:16Z emaste $");
   32 
   33 #include <sys/param.h>
   34 #include <sys/bus.h>
   35 #include <sys/systm.h>
   36 #include <sys/types.h>
   37 #include <sys/malloc.h>
   38 #include <sys/kernel.h>
   39 #include <sys/time.h>
   40 #include <sys/conf.h>
   41 #include <sys/fcntl.h>
   42 #include <sys/md5.h>
   43 #include <sys/interrupt.h>
   44 #include <sys/sbuf.h>
   45 #include <sys/taskqueue.h>
   46 
   47 #include <sys/lock.h>
   48 #include <sys/mutex.h>
   49 #include <sys/sysctl.h>
   50 #include <sys/kthread.h>
   51 
   52 #ifdef PC98
   53 #include <pc98/pc98/pc98_machdep.h>     /* geometry translation */
   54 #endif
   55 
   56 #include <cam/cam.h>
   57 #include <cam/cam_ccb.h>
   58 #include <cam/cam_periph.h>
   59 #include <cam/cam_sim.h>
   60 #include <cam/cam_xpt.h>
   61 #include <cam/cam_xpt_sim.h>
   62 #include <cam/cam_xpt_periph.h>
   63 #include <cam/cam_debug.h>
   64 
   65 #include <cam/scsi/scsi_all.h>
   66 #include <cam/scsi/scsi_message.h>
   67 #include <cam/scsi/scsi_pass.h>
   68 #include <machine/stdarg.h>     /* for xpt_print below */
   69 #include "opt_cam.h"
   70 
   71 /* Datastructures internal to the xpt layer */
   72 MALLOC_DEFINE(M_CAMXPT, "CAM XPT", "CAM XPT buffers");
   73 
   74 /* Object for defering XPT actions to a taskqueue */
   75 struct xpt_task {
   76         struct task     task;
   77         void            *data1;
   78         uintptr_t       data2;
   79 };
   80 
   81 /*
   82  * Definition of an async handler callback block.  These are used to add
   83  * SIMs and peripherals to the async callback lists.
   84  */
   85 struct async_node {
   86         SLIST_ENTRY(async_node) links;
   87         u_int32_t       event_enable;   /* Async Event enables */
   88         void            (*callback)(void *arg, u_int32_t code,
   89                                     struct cam_path *path, void *args);
   90         void            *callback_arg;
   91 };
   92 
   93 SLIST_HEAD(async_list, async_node);
   94 SLIST_HEAD(periph_list, cam_periph);
   95 
   96 /*
   97  * This is the maximum number of high powered commands (e.g. start unit)
   98  * that can be outstanding at a particular time.
   99  */
  100 #ifndef CAM_MAX_HIGHPOWER
  101 #define CAM_MAX_HIGHPOWER  4
  102 #endif
  103 
  104 /*
  105  * Structure for queueing a device in a run queue.
  106  * There is one run queue for allocating new ccbs,
  107  * and another for sending ccbs to the controller.
  108  */
  109 struct cam_ed_qinfo {
  110         cam_pinfo pinfo;
  111         struct    cam_ed *device;
  112 };
  113 
  114 /*
  115  * The CAM EDT (Existing Device Table) contains the device information for
  116  * all devices for all busses in the system.  The table contains a
  117  * cam_ed structure for each device on the bus.
  118  */
  119 struct cam_ed {
  120         TAILQ_ENTRY(cam_ed) links;
  121         struct  cam_ed_qinfo alloc_ccb_entry;
  122         struct  cam_ed_qinfo send_ccb_entry;
  123         struct  cam_et   *target;
  124         struct  cam_sim  *sim;
  125         lun_id_t         lun_id;
  126         struct  camq drvq;              /*
  127                                          * Queue of type drivers wanting to do
  128                                          * work on this device.
  129                                          */
  130         struct  cam_ccbq ccbq;          /* Queue of pending ccbs */
  131         struct  async_list asyncs;      /* Async callback info for this B/T/L */
  132         struct  periph_list periphs;    /* All attached devices */
  133         u_int   generation;             /* Generation number */
  134         struct  cam_periph *owner;      /* Peripheral driver's ownership tag */
  135         struct  xpt_quirk_entry *quirk; /* Oddities about this device */
  136                                         /* Storage for the inquiry data */
  137         cam_proto        protocol;
  138         u_int            protocol_version;
  139         cam_xport        transport;
  140         u_int            transport_version;
  141         struct           scsi_inquiry_data inq_data;
  142         u_int8_t         inq_flags;     /*
  143                                          * Current settings for inquiry flags.
  144                                          * This allows us to override settings
  145                                          * like disconnection and tagged
  146                                          * queuing for a device.
  147                                          */
  148         u_int8_t         queue_flags;   /* Queue flags from the control page */
  149         u_int8_t         serial_num_len;
  150         u_int8_t        *serial_num;
  151         u_int32_t        qfrozen_cnt;
  152         u_int32_t        flags;
  153 #define CAM_DEV_UNCONFIGURED            0x01
  154 #define CAM_DEV_REL_TIMEOUT_PENDING     0x02
  155 #define CAM_DEV_REL_ON_COMPLETE         0x04
  156 #define CAM_DEV_REL_ON_QUEUE_EMPTY      0x08
  157 #define CAM_DEV_RESIZE_QUEUE_NEEDED     0x10
  158 #define CAM_DEV_TAG_AFTER_COUNT         0x20
  159 #define CAM_DEV_INQUIRY_DATA_VALID      0x40
  160 #define CAM_DEV_IN_DV                   0x80
  161 #define CAM_DEV_DV_HIT_BOTTOM           0x100
  162         u_int32_t        tag_delay_count;
  163 #define CAM_TAG_DELAY_COUNT             5
  164         u_int32_t        tag_saved_openings;
  165         u_int32_t        refcount;
  166         struct callout   callout;
  167 };
  168 
  169 /*
  170  * Each target is represented by an ET (Existing Target).  These
  171  * entries are created when a target is successfully probed with an
  172  * identify, and removed when a device fails to respond after a number
  173  * of retries, or a bus rescan finds the device missing.
  174  */
  175 struct cam_et {
  176         TAILQ_HEAD(, cam_ed) ed_entries;
  177         TAILQ_ENTRY(cam_et) links;
  178         struct  cam_eb  *bus;
  179         target_id_t     target_id;
  180         u_int32_t       refcount;
  181         u_int           generation;
  182         struct          timeval last_reset;
  183 };
  184 
  185 /*
  186  * Each bus is represented by an EB (Existing Bus).  These entries
  187  * are created by calls to xpt_bus_register and deleted by calls to
  188  * xpt_bus_deregister.
  189  */
  190 struct cam_eb {
  191         TAILQ_HEAD(, cam_et) et_entries;
  192         TAILQ_ENTRY(cam_eb)  links;
  193         path_id_t            path_id;
  194         struct cam_sim       *sim;
  195         struct timeval       last_reset;
  196         u_int32_t            flags;
  197 #define CAM_EB_RUNQ_SCHEDULED   0x01
  198         u_int32_t            refcount;
  199         u_int                generation;
  200         device_t             parent_dev;
  201 };
  202 
  203 struct cam_path {
  204         struct cam_periph *periph;
  205         struct cam_eb     *bus;
  206         struct cam_et     *target;
  207         struct cam_ed     *device;
  208 };
  209 
  210 struct xpt_quirk_entry {
  211         struct scsi_inquiry_pattern inq_pat;
  212         u_int8_t quirks;
  213 #define CAM_QUIRK_NOLUNS        0x01
  214 #define CAM_QUIRK_NOSERIAL      0x02
  215 #define CAM_QUIRK_HILUNS        0x04
  216 #define CAM_QUIRK_NOHILUNS      0x08
  217         u_int mintags;
  218         u_int maxtags;
  219 };
  220 
  221 static int cam_srch_hi = 0;
  222 TUNABLE_INT("kern.cam.cam_srch_hi", &cam_srch_hi);
  223 static int sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS);
  224 SYSCTL_PROC(_kern_cam, OID_AUTO, cam_srch_hi, CTLTYPE_INT|CTLFLAG_RW, 0, 0,
  225     sysctl_cam_search_luns, "I",
  226     "allow search above LUN 7 for SCSI3 and greater devices");
  227 
  228 #define CAM_SCSI2_MAXLUN        8
  229 /*
  230  * If we're not quirked to search <= the first 8 luns
  231  * and we are either quirked to search above lun 8,
  232  * or we're > SCSI-2 and we've enabled hilun searching,
  233  * or we're > SCSI-2 and the last lun was a success,
  234  * we can look for luns above lun 8.
  235  */
  236 #define CAN_SRCH_HI_SPARSE(dv)                          \
  237   (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0)      \
  238   && ((dv->quirk->quirks & CAM_QUIRK_HILUNS)            \
  239   || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2 && cam_srch_hi)))
  240 
  241 #define CAN_SRCH_HI_DENSE(dv)                           \
  242   (((dv->quirk->quirks & CAM_QUIRK_NOHILUNS) == 0)      \
  243   && ((dv->quirk->quirks & CAM_QUIRK_HILUNS)            \
  244   || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2)))
  245 
  246 typedef enum {
  247         XPT_FLAG_OPEN           = 0x01
  248 } xpt_flags;
  249 
  250 struct xpt_softc {
  251         xpt_flags               flags;
  252         u_int32_t               xpt_generation;
  253 
  254         /* number of high powered commands that can go through right now */
  255         STAILQ_HEAD(highpowerlist, ccb_hdr)     highpowerq;
  256         int                     num_highpower;
  257 
  258         /* queue for handling async rescan requests. */
  259         TAILQ_HEAD(, ccb_hdr) ccb_scanq;
  260 
  261         /* Registered busses */
  262         TAILQ_HEAD(,cam_eb)     xpt_busses;
  263         u_int                   bus_generation;
  264 
  265         struct intr_config_hook *xpt_config_hook;
  266 
  267         struct mtx              xpt_topo_lock;
  268         struct mtx              xpt_lock;
  269 };
  270 
  271 static const char quantum[] = "QUANTUM";
  272 static const char sony[] = "SONY";
  273 static const char west_digital[] = "WDIGTL";
  274 static const char samsung[] = "SAMSUNG";
  275 static const char seagate[] = "SEAGATE";
  276 static const char microp[] = "MICROP";
  277 
  278 static struct xpt_quirk_entry xpt_quirk_table[] =
  279 {
  280         {
  281                 /* Reports QUEUE FULL for temporary resource shortages */
  282                 { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP39100*", "*" },
  283                 /*quirks*/0, /*mintags*/24, /*maxtags*/32
  284         },
  285         {
  286                 /* Reports QUEUE FULL for temporary resource shortages */
  287                 { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP34550*", "*" },
  288                 /*quirks*/0, /*mintags*/24, /*maxtags*/32
  289         },
  290         {
  291                 /* Reports QUEUE FULL for temporary resource shortages */
  292                 { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP32275*", "*" },
  293                 /*quirks*/0, /*mintags*/24, /*maxtags*/32
  294         },
  295         {
  296                 /* Broken tagged queuing drive */
  297                 { T_DIRECT, SIP_MEDIA_FIXED, microp, "4421-07*", "*" },
  298                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  299         },
  300         {
  301                 /* Broken tagged queuing drive */
  302                 { T_DIRECT, SIP_MEDIA_FIXED, "HP", "C372*", "*" },
  303                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  304         },
  305         {
  306                 /* Broken tagged queuing drive */
  307                 { T_DIRECT, SIP_MEDIA_FIXED, microp, "3391*", "x43h" },
  308                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  309         },
  310         {
  311                 /*
  312                  * Unfortunately, the Quantum Atlas III has the same
  313                  * problem as the Atlas II drives above.
  314                  * Reported by: "Johan Granlund" <johan@granlund.nu>
  315                  *
  316                  * For future reference, the drive with the problem was:
  317                  * QUANTUM QM39100TD-SW N1B0
  318                  *
  319                  * It's possible that Quantum will fix the problem in later
  320                  * firmware revisions.  If that happens, the quirk entry
  321                  * will need to be made specific to the firmware revisions
  322                  * with the problem.
  323                  *
  324                  */
  325                 /* Reports QUEUE FULL for temporary resource shortages */
  326                 { T_DIRECT, SIP_MEDIA_FIXED, quantum, "QM39100*", "*" },
  327                 /*quirks*/0, /*mintags*/24, /*maxtags*/32
  328         },
  329         {
  330                 /*
  331                  * 18 Gig Atlas III, same problem as the 9G version.
  332                  * Reported by: Andre Albsmeier
  333                  *              <andre.albsmeier@mchp.siemens.de>
  334                  *
  335                  * For future reference, the drive with the problem was:
  336                  * QUANTUM QM318000TD-S N491
  337                  */
  338                 /* Reports QUEUE FULL for temporary resource shortages */
  339                 { T_DIRECT, SIP_MEDIA_FIXED, quantum, "QM318000*", "*" },
  340                 /*quirks*/0, /*mintags*/24, /*maxtags*/32
  341         },
  342         {
  343                 /*
  344                  * Broken tagged queuing drive
  345                  * Reported by: Bret Ford <bford@uop.cs.uop.edu>
  346                  *         and: Martin Renters <martin@tdc.on.ca>
  347                  */
  348                 { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST410800*", "71*" },
  349                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  350         },
  351                 /*
  352                  * The Seagate Medalist Pro drives have very poor write
  353                  * performance with anything more than 2 tags.
  354                  *
  355                  * Reported by:  Paul van der Zwan <paulz@trantor.xs4all.nl>
  356                  * Drive:  <SEAGATE ST36530N 1444>
  357                  *
  358                  * Reported by:  Jeremy Lea <reg@shale.csir.co.za>
  359                  * Drive:  <SEAGATE ST34520W 1281>
  360                  *
  361                  * No one has actually reported that the 9G version
  362                  * (ST39140*) of the Medalist Pro has the same problem, but
  363                  * we're assuming that it does because the 4G and 6.5G
  364                  * versions of the drive are broken.
  365                  */
  366         {
  367                 { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST34520*", "*"},
  368                 /*quirks*/0, /*mintags*/2, /*maxtags*/2
  369         },
  370         {
  371                 { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST36530*", "*"},
  372                 /*quirks*/0, /*mintags*/2, /*maxtags*/2
  373         },
  374         {
  375                 { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST39140*", "*"},
  376                 /*quirks*/0, /*mintags*/2, /*maxtags*/2
  377         },
  378         {
  379                 /*
  380                  * Slow when tagged queueing is enabled.  Write performance
  381                  * steadily drops off with more and more concurrent
  382                  * transactions.  Best sequential write performance with
  383                  * tagged queueing turned off and write caching turned on.
  384                  *
  385                  * PR:  kern/10398
  386                  * Submitted by:  Hideaki Okada <hokada@isl.melco.co.jp>
  387                  * Drive:  DCAS-34330 w/ "S65A" firmware.
  388                  *
  389                  * The drive with the problem had the "S65A" firmware
  390                  * revision, and has also been reported (by Stephen J.
  391                  * Roznowski <sjr@home.net>) for a drive with the "S61A"
  392                  * firmware revision.
  393                  *
  394                  * Although no one has reported problems with the 2 gig
  395                  * version of the DCAS drive, the assumption is that it
  396                  * has the same problems as the 4 gig version.  Therefore
  397                  * this quirk entries disables tagged queueing for all
  398                  * DCAS drives.
  399                  */
  400                 { T_DIRECT, SIP_MEDIA_FIXED, "IBM", "DCAS*", "*" },
  401                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  402         },
  403         {
  404                 /* Broken tagged queuing drive */
  405                 { T_DIRECT, SIP_MEDIA_REMOVABLE, "iomega", "jaz*", "*" },
  406                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  407         },
  408         {
  409                 /* Broken tagged queuing drive */
  410                 { T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CFP2107*", "*" },
  411                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  412         },
  413         {
  414                 /* This does not support other than LUN 0 */
  415                 { T_DIRECT, SIP_MEDIA_FIXED, "VMware*", "*", "*" },
  416                 CAM_QUIRK_NOLUNS, /*mintags*/2, /*maxtags*/255
  417         },
  418         {
  419                 /*
  420                  * Broken tagged queuing drive.
  421                  * Submitted by:
  422                  * NAKAJI Hiroyuki <nakaji@zeisei.dpri.kyoto-u.ac.jp>
  423                  * in PR kern/9535
  424                  */
  425                 { T_DIRECT, SIP_MEDIA_FIXED, samsung, "WN34324U*", "*" },
  426                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  427         },
  428         {
  429                 /*
  430                  * Slow when tagged queueing is enabled. (1.5MB/sec versus
  431                  * 8MB/sec.)
  432                  * Submitted by: Andrew Gallatin <gallatin@cs.duke.edu>
  433                  * Best performance with these drives is achieved with
  434                  * tagged queueing turned off, and write caching turned on.
  435                  */
  436                 { T_DIRECT, SIP_MEDIA_FIXED, west_digital, "WDE*", "*" },
  437                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  438         },
  439         {
  440                 /*
  441                  * Slow when tagged queueing is enabled. (1.5MB/sec versus
  442                  * 8MB/sec.)
  443                  * Submitted by: Andrew Gallatin <gallatin@cs.duke.edu>
  444                  * Best performance with these drives is achieved with
  445                  * tagged queueing turned off, and write caching turned on.
  446                  */
  447                 { T_DIRECT, SIP_MEDIA_FIXED, west_digital, "ENTERPRISE", "*" },
  448                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  449         },
  450         {
  451                 /*
  452                  * Doesn't handle queue full condition correctly,
  453                  * so we need to limit maxtags to what the device
  454                  * can handle instead of determining this automatically.
  455                  */
  456                 { T_DIRECT, SIP_MEDIA_FIXED, samsung, "WN321010S*", "*" },
  457                 /*quirks*/0, /*mintags*/2, /*maxtags*/32
  458         },
  459         {
  460                 /* Really only one LUN */
  461                 { T_ENCLOSURE, SIP_MEDIA_FIXED, "SUN", "SENA", "*" },
  462                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  463         },
  464         {
  465                 /* I can't believe we need a quirk for DPT volumes. */
  466                 { T_ANY, SIP_MEDIA_FIXED|SIP_MEDIA_REMOVABLE, "DPT", "*", "*" },
  467                 CAM_QUIRK_NOLUNS,
  468                 /*mintags*/0, /*maxtags*/255
  469         },
  470         {
  471                 /*
  472                  * Many Sony CDROM drives don't like multi-LUN probing.
  473                  */
  474                 { T_CDROM, SIP_MEDIA_REMOVABLE, sony, "CD-ROM CDU*", "*" },
  475                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  476         },
  477         {
  478                 /*
  479                  * This drive doesn't like multiple LUN probing.
  480                  * Submitted by:  Parag Patel <parag@cgt.com>
  481                  */
  482                 { T_WORM, SIP_MEDIA_REMOVABLE, sony, "CD-R   CDU9*", "*" },
  483                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  484         },
  485         {
  486                 { T_WORM, SIP_MEDIA_REMOVABLE, "YAMAHA", "CDR100*", "*" },
  487                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  488         },
  489         {
  490                 /*
  491                  * The 8200 doesn't like multi-lun probing, and probably
  492                  * don't like serial number requests either.
  493                  */
  494                 {
  495                         T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "EXABYTE",
  496                         "EXB-8200*", "*"
  497                 },
  498                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  499         },
  500         {
  501                 /*
  502                  * Let's try the same as above, but for a drive that says
  503                  * it's an IPL-6860 but is actually an EXB 8200.
  504                  */
  505                 {
  506                         T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "EXABYTE",
  507                         "IPL-6860*", "*"
  508                 },
  509                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  510         },
  511         {
  512                 /*
  513                  * These Hitachi drives don't like multi-lun probing.
  514                  * The PR submitter has a DK319H, but says that the Linux
  515                  * kernel has a similar work-around for the DK312 and DK314,
  516                  * so all DK31* drives are quirked here.
  517                  * PR:            misc/18793
  518                  * Submitted by:  Paul Haddad <paul@pth.com>
  519                  */
  520                 { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "DK31*", "*" },
  521                 CAM_QUIRK_NOLUNS, /*mintags*/2, /*maxtags*/255
  522         },
  523         {
  524                 /*
  525                  * The Hitachi CJ series with J8A8 firmware apparantly has
  526                  * problems with tagged commands.
  527                  * PR: 23536
  528                  * Reported by: amagai@nue.org
  529                  */
  530                 { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "DK32CJ*", "J8A8" },
  531                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  532         },
  533         {
  534                 /*
  535                  * These are the large storage arrays.
  536                  * Submitted by:  William Carrel <william.carrel@infospace.com>
  537                  */
  538                 { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "OPEN*", "*" },
  539                 CAM_QUIRK_HILUNS, 2, 1024
  540         },
  541         {
  542                 /*
  543                  * This old revision of the TDC3600 is also SCSI-1, and
  544                  * hangs upon serial number probing.
  545                  */
  546                 {
  547                         T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
  548                         " TDC 3600", "U07:"
  549                 },
  550                 CAM_QUIRK_NOSERIAL, /*mintags*/0, /*maxtags*/
  551         },
  552         {
  553                 /*
  554                  * Would repond to all LUNs if asked for.
  555                  */
  556                 {
  557                         T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "CALIPER",
  558                         "CP150", "*"
  559                 },
  560                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  561         },
  562         {
  563                 /*
  564                  * Would repond to all LUNs if asked for.
  565                  */
  566                 {
  567                         T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "KENNEDY",
  568                         "96X2*", "*"
  569                 },
  570                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  571         },
  572         {
  573                 /* Submitted by: Matthew Dodd <winter@jurai.net> */
  574                 { T_PROCESSOR, SIP_MEDIA_FIXED, "Cabletrn", "EA41*", "*" },
  575                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  576         },
  577         {
  578                 /* Submitted by: Matthew Dodd <winter@jurai.net> */
  579                 { T_PROCESSOR, SIP_MEDIA_FIXED, "CABLETRN", "EA41*", "*" },
  580                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  581         },
  582         {
  583                 /* TeraSolutions special settings for TRC-22 RAID */
  584                 { T_DIRECT, SIP_MEDIA_FIXED, "TERASOLU", "TRC-22", "*" },
  585                   /*quirks*/0, /*mintags*/55, /*maxtags*/255
  586         },
  587         {
  588                 /* Veritas Storage Appliance */
  589                 { T_DIRECT, SIP_MEDIA_FIXED, "VERITAS", "*", "*" },
  590                   CAM_QUIRK_HILUNS, /*mintags*/2, /*maxtags*/1024
  591         },
  592         {
  593                 /*
  594                  * Would respond to all LUNs.  Device type and removable
  595                  * flag are jumper-selectable.
  596                  */
  597                 { T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, "MaxOptix",
  598                   "Tahiti 1", "*"
  599                 },
  600                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  601         },
  602         {
  603                 /* EasyRAID E5A aka. areca ARC-6010 */
  604                 { T_DIRECT, SIP_MEDIA_FIXED, "easyRAID", "*", "*" },
  605                   CAM_QUIRK_NOHILUNS, /*mintags*/2, /*maxtags*/255
  606         },
  607         {
  608                 { T_ENCLOSURE, SIP_MEDIA_FIXED, "DP", "BACKPLANE", "*" },
  609                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  610         },
  611         {
  612                 /* Default tagged queuing parameters for all devices */
  613                 {
  614                   T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
  615                   /*vendor*/"*", /*product*/"*", /*revision*/"*"
  616                 },
  617                 /*quirks*/0, /*mintags*/2, /*maxtags*/255
  618         },
  619 };
  620 
  621 static const int xpt_quirk_table_size =
  622         sizeof(xpt_quirk_table) / sizeof(*xpt_quirk_table);
  623 
  624 typedef enum {
  625         DM_RET_COPY             = 0x01,
  626         DM_RET_FLAG_MASK        = 0x0f,
  627         DM_RET_NONE             = 0x00,
  628         DM_RET_STOP             = 0x10,
  629         DM_RET_DESCEND          = 0x20,
  630         DM_RET_ERROR            = 0x30,
  631         DM_RET_ACTION_MASK      = 0xf0
  632 } dev_match_ret;
  633 
  634 typedef enum {
  635         XPT_DEPTH_BUS,
  636         XPT_DEPTH_TARGET,
  637         XPT_DEPTH_DEVICE,
  638         XPT_DEPTH_PERIPH
  639 } xpt_traverse_depth;
  640 
  641 struct xpt_traverse_config {
  642         xpt_traverse_depth      depth;
  643         void                    *tr_func;
  644         void                    *tr_arg;
  645 };
  646 
  647 typedef int     xpt_busfunc_t (struct cam_eb *bus, void *arg);
  648 typedef int     xpt_targetfunc_t (struct cam_et *target, void *arg);
  649 typedef int     xpt_devicefunc_t (struct cam_ed *device, void *arg);
  650 typedef int     xpt_periphfunc_t (struct cam_periph *periph, void *arg);
  651 typedef int     xpt_pdrvfunc_t (struct periph_driver **pdrv, void *arg);
  652 
  653 /* Transport layer configuration information */
  654 static struct xpt_softc xsoftc;
  655 
  656 /* Queues for our software interrupt handler */
  657 typedef TAILQ_HEAD(cam_isrq, ccb_hdr) cam_isrq_t;
  658 typedef TAILQ_HEAD(cam_simq, cam_sim) cam_simq_t;
  659 static cam_simq_t cam_simq;
  660 static struct mtx cam_simq_lock;
  661 
  662 /* Pointers to software interrupt handlers */
  663 static void *cambio_ih;
  664 
  665 struct cam_periph *xpt_periph;
  666 
  667 static periph_init_t xpt_periph_init;
  668 
  669 static periph_init_t probe_periph_init;
  670 
  671 static struct periph_driver xpt_driver =
  672 {
  673         xpt_periph_init, "xpt",
  674         TAILQ_HEAD_INITIALIZER(xpt_driver.units)
  675 };
  676 
  677 static struct periph_driver probe_driver =
  678 {
  679         probe_periph_init, "probe",
  680         TAILQ_HEAD_INITIALIZER(probe_driver.units)
  681 };
  682 
  683 PERIPHDRIVER_DECLARE(xpt, xpt_driver);
  684 PERIPHDRIVER_DECLARE(probe, probe_driver);
  685 
  686 
  687 static d_open_t xptopen;
  688 static d_close_t xptclose;
  689 static d_ioctl_t xptioctl;
  690 
  691 static struct cdevsw xpt_cdevsw = {
  692         .d_version =    D_VERSION,
  693         .d_flags =      0,
  694         .d_open =       xptopen,
  695         .d_close =      xptclose,
  696         .d_ioctl =      xptioctl,
  697         .d_name =       "xpt",
  698 };
  699 
  700 
  701 /* Storage for debugging datastructures */
  702 #ifdef  CAMDEBUG
  703 struct cam_path *cam_dpath;
  704 u_int32_t cam_dflags;
  705 u_int32_t cam_debug_delay;
  706 #endif
  707 
  708 #if defined(CAM_DEBUG_FLAGS) && !defined(CAMDEBUG)
  709 #error "You must have options CAMDEBUG to use options CAM_DEBUG_FLAGS"
  710 #endif
  711 
  712 /*
  713  * In order to enable the CAM_DEBUG_* options, the user must have CAMDEBUG
  714  * enabled.  Also, the user must have either none, or all of CAM_DEBUG_BUS,
  715  * CAM_DEBUG_TARGET, and CAM_DEBUG_LUN specified.
  716  */
  717 #if defined(CAM_DEBUG_BUS) || defined(CAM_DEBUG_TARGET) \
  718     || defined(CAM_DEBUG_LUN)
  719 #ifdef CAMDEBUG
  720 #if !defined(CAM_DEBUG_BUS) || !defined(CAM_DEBUG_TARGET) \
  721     || !defined(CAM_DEBUG_LUN)
  722 #error "You must define all or none of CAM_DEBUG_BUS, CAM_DEBUG_TARGET \
  723         and CAM_DEBUG_LUN"
  724 #endif /* !CAM_DEBUG_BUS || !CAM_DEBUG_TARGET || !CAM_DEBUG_LUN */
  725 #else /* !CAMDEBUG */
  726 #error "You must use options CAMDEBUG if you use the CAM_DEBUG_* options"
  727 #endif /* CAMDEBUG */
  728 #endif /* CAM_DEBUG_BUS || CAM_DEBUG_TARGET || CAM_DEBUG_LUN */
  729 
  730 /* Our boot-time initialization hook */
  731 static int cam_module_event_handler(module_t, int /*modeventtype_t*/, void *);
  732 
  733 static moduledata_t cam_moduledata = {
  734         "cam",
  735         cam_module_event_handler,
  736         NULL
  737 };
  738 
  739 static int      xpt_init(void *);
  740 
  741 DECLARE_MODULE(cam, cam_moduledata, SI_SUB_CONFIGURE, SI_ORDER_SECOND);
  742 MODULE_VERSION(cam, 1);
  743 
  744 
  745 static cam_status       xpt_compile_path(struct cam_path *new_path,
  746                                          struct cam_periph *perph,
  747                                          path_id_t path_id,
  748                                          target_id_t target_id,
  749                                          lun_id_t lun_id);
  750 
  751 static void             xpt_release_path(struct cam_path *path);
  752 
  753 static void             xpt_async_bcast(struct async_list *async_head,
  754                                         u_int32_t async_code,
  755                                         struct cam_path *path,
  756                                         void *async_arg);
  757 static void             xpt_dev_async(u_int32_t async_code,
  758                                       struct cam_eb *bus,
  759                                       struct cam_et *target,
  760                                       struct cam_ed *device,
  761                                       void *async_arg);
  762 static path_id_t xptnextfreepathid(void);
  763 static path_id_t xptpathid(const char *sim_name, int sim_unit, int sim_bus);
  764 static union ccb *xpt_get_ccb(struct cam_ed *device);
  765 static int       xpt_schedule_dev(struct camq *queue, cam_pinfo *dev_pinfo,
  766                                   u_int32_t new_priority);
  767 static void      xpt_run_dev_allocq(struct cam_eb *bus);
  768 static void      xpt_run_dev_sendq(struct cam_eb *bus);
  769 static timeout_t xpt_release_devq_timeout;
  770 static void      xpt_release_simq_timeout(void *arg) __unused;
  771 static void      xpt_release_bus(struct cam_eb *bus);
  772 static void      xpt_release_devq_device(struct cam_ed *dev, u_int count,
  773                                          int run_queue);
  774 static struct cam_et*
  775                  xpt_alloc_target(struct cam_eb *bus, target_id_t target_id);
  776 static void      xpt_release_target(struct cam_eb *bus, struct cam_et *target);
  777 static struct cam_ed*
  778                  xpt_alloc_device(struct cam_eb *bus, struct cam_et *target,
  779                                   lun_id_t lun_id);
  780 static void      xpt_release_device(struct cam_eb *bus, struct cam_et *target,
  781                                     struct cam_ed *device);
  782 static u_int32_t xpt_dev_ccbq_resize(struct cam_path *path, int newopenings);
  783 static struct cam_eb*
  784                  xpt_find_bus(path_id_t path_id);
  785 static struct cam_et*
  786                  xpt_find_target(struct cam_eb *bus, target_id_t target_id);
  787 static struct cam_ed*
  788                  xpt_find_device(struct cam_et *target, lun_id_t lun_id);
  789 static void      xpt_scan_bus(struct cam_periph *periph, union ccb *ccb);
  790 static void      xpt_scan_lun(struct cam_periph *periph,
  791                               struct cam_path *path, cam_flags flags,
  792                               union ccb *ccb);
  793 static void      xptscandone(struct cam_periph *periph, union ccb *done_ccb);
  794 static xpt_busfunc_t    xptconfigbuscountfunc;
  795 static xpt_busfunc_t    xptconfigfunc;
  796 static void      xpt_config(void *arg);
  797 static xpt_devicefunc_t xptpassannouncefunc;
  798 static void      xpt_finishconfig(struct cam_periph *periph, union ccb *ccb);
  799 static void      xptaction(struct cam_sim *sim, union ccb *work_ccb);
  800 static void      xptpoll(struct cam_sim *sim);
  801 static void      camisr(void *);
  802 static void      camisr_runqueue(void *);
  803 static dev_match_ret    xptbusmatch(struct dev_match_pattern *patterns,
  804                                     u_int num_patterns, struct cam_eb *bus);
  805 static dev_match_ret    xptdevicematch(struct dev_match_pattern *patterns,
  806                                        u_int num_patterns,
  807                                        struct cam_ed *device);
  808 static dev_match_ret    xptperiphmatch(struct dev_match_pattern *patterns,
  809                                        u_int num_patterns,
  810                                        struct cam_periph *periph);
  811 static xpt_busfunc_t    xptedtbusfunc;
  812 static xpt_targetfunc_t xptedttargetfunc;
  813 static xpt_devicefunc_t xptedtdevicefunc;
  814 static xpt_periphfunc_t xptedtperiphfunc;
  815 static xpt_pdrvfunc_t   xptplistpdrvfunc;
  816 static xpt_periphfunc_t xptplistperiphfunc;
  817 static int              xptedtmatch(struct ccb_dev_match *cdm);
  818 static int              xptperiphlistmatch(struct ccb_dev_match *cdm);
  819 static int              xptbustraverse(struct cam_eb *start_bus,
  820                                        xpt_busfunc_t *tr_func, void *arg);
  821 static int              xpttargettraverse(struct cam_eb *bus,
  822                                           struct cam_et *start_target,
  823                                           xpt_targetfunc_t *tr_func, void *arg);
  824 static int              xptdevicetraverse(struct cam_et *target,
  825                                           struct cam_ed *start_device,
  826                                           xpt_devicefunc_t *tr_func, void *arg);
  827 static int              xptperiphtraverse(struct cam_ed *device,
  828                                           struct cam_periph *start_periph,
  829                                           xpt_periphfunc_t *tr_func, void *arg);
  830 static int              xptpdrvtraverse(struct periph_driver **start_pdrv,
  831                                         xpt_pdrvfunc_t *tr_func, void *arg);
  832 static int              xptpdperiphtraverse(struct periph_driver **pdrv,
  833                                             struct cam_periph *start_periph,
  834                                             xpt_periphfunc_t *tr_func,
  835                                             void *arg);
  836 static xpt_busfunc_t    xptdefbusfunc;
  837 static xpt_targetfunc_t xptdeftargetfunc;
  838 static xpt_devicefunc_t xptdefdevicefunc;
  839 static xpt_periphfunc_t xptdefperiphfunc;
  840 static int              xpt_for_all_busses(xpt_busfunc_t *tr_func, void *arg);
  841 static int              xpt_for_all_devices(xpt_devicefunc_t *tr_func,
  842                                             void *arg);
  843 static xpt_devicefunc_t xptsetasyncfunc;
  844 static xpt_busfunc_t    xptsetasyncbusfunc;
  845 static cam_status       xptregister(struct cam_periph *periph,
  846                                     void *arg);
  847 static cam_status       proberegister(struct cam_periph *periph,
  848                                       void *arg);
  849 static void      probeschedule(struct cam_periph *probe_periph);
  850 static void      probestart(struct cam_periph *periph, union ccb *start_ccb);
  851 static void      proberequestdefaultnegotiation(struct cam_periph *periph);
  852 static int       proberequestbackoff(struct cam_periph *periph,
  853                                      struct cam_ed *device);
  854 static void      probedone(struct cam_periph *periph, union ccb *done_ccb);
  855 static void      probecleanup(struct cam_periph *periph);
  856 static void      xpt_find_quirk(struct cam_ed *device);
  857 static void      xpt_devise_transport(struct cam_path *path);
  858 static void      xpt_set_transfer_settings(struct ccb_trans_settings *cts,
  859                                            struct cam_ed *device,
  860                                            int async_update);
  861 static void      xpt_toggle_tags(struct cam_path *path);
  862 static void      xpt_start_tags(struct cam_path *path);
  863 static __inline int xpt_schedule_dev_allocq(struct cam_eb *bus,
  864                                             struct cam_ed *dev);
  865 static __inline int xpt_schedule_dev_sendq(struct cam_eb *bus,
  866                                            struct cam_ed *dev);
  867 static __inline int periph_is_queued(struct cam_periph *periph);
  868 static __inline int device_is_alloc_queued(struct cam_ed *device);
  869 static __inline int device_is_send_queued(struct cam_ed *device);
  870 static __inline int dev_allocq_is_runnable(struct cam_devq *devq);
  871 
  872 static __inline int
  873 xpt_schedule_dev_allocq(struct cam_eb *bus, struct cam_ed *dev)
  874 {
  875         int retval;
  876 
  877         if (dev->ccbq.devq_openings > 0) {
  878                 if ((dev->flags & CAM_DEV_RESIZE_QUEUE_NEEDED) != 0) {
  879                         cam_ccbq_resize(&dev->ccbq,
  880                                         dev->ccbq.dev_openings
  881                                         + dev->ccbq.dev_active);
  882                         dev->flags &= ~CAM_DEV_RESIZE_QUEUE_NEEDED;
  883                 }
  884                 /*
  885                  * The priority of a device waiting for CCB resources
  886                  * is that of the the highest priority peripheral driver
  887                  * enqueued.
  888                  */
  889                 retval = xpt_schedule_dev(&bus->sim->devq->alloc_queue,
  890                                           &dev->alloc_ccb_entry.pinfo,
  891                                           CAMQ_GET_HEAD(&dev->drvq)->priority);
  892         } else {
  893                 retval = 0;
  894         }
  895 
  896         return (retval);
  897 }
  898 
  899 static __inline int
  900 xpt_schedule_dev_sendq(struct cam_eb *bus, struct cam_ed *dev)
  901 {
  902         int     retval;
  903 
  904         if (dev->ccbq.dev_openings > 0) {
  905                 /*
  906                  * The priority of a device waiting for controller
  907                  * resources is that of the the highest priority CCB
  908                  * enqueued.
  909                  */
  910                 retval =
  911                     xpt_schedule_dev(&bus->sim->devq->send_queue,
  912                                      &dev->send_ccb_entry.pinfo,
  913                                      CAMQ_GET_HEAD(&dev->ccbq.queue)->priority);
  914         } else {
  915                 retval = 0;
  916         }
  917         return (retval);
  918 }
  919 
  920 static __inline int
  921 periph_is_queued(struct cam_periph *periph)
  922 {
  923         return (periph->pinfo.index != CAM_UNQUEUED_INDEX);
  924 }
  925 
  926 static __inline int
  927 device_is_alloc_queued(struct cam_ed *device)
  928 {
  929         return (device->alloc_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX);
  930 }
  931 
  932 static __inline int
  933 device_is_send_queued(struct cam_ed *device)
  934 {
  935         return (device->send_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX);
  936 }
  937 
  938 static __inline int
  939 dev_allocq_is_runnable(struct cam_devq *devq)
  940 {
  941         /*
  942          * Have work to do.
  943          * Have space to do more work.
  944          * Allowed to do work.
  945          */
  946         return ((devq->alloc_queue.qfrozen_cnt == 0)
  947              && (devq->alloc_queue.entries > 0)
  948              && (devq->alloc_openings > 0));
  949 }
  950 
  951 static void
  952 xpt_periph_init()
  953 {
  954         make_dev(&xpt_cdevsw, 0, UID_ROOT, GID_OPERATOR, 0600, "xpt0");
  955 }
  956 
  957 static void
  958 probe_periph_init()
  959 {
  960 }
  961 
  962 
  963 static void
  964 xptdone(struct cam_periph *periph, union ccb *done_ccb)
  965 {
  966         /* Caller will release the CCB */
  967         wakeup(&done_ccb->ccb_h.cbfcnp);
  968 }
  969 
  970 static int
  971 xptopen(struct cdev *dev, int flags, int fmt, struct thread *td)
  972 {
  973 
  974         /*
  975          * Only allow read-write access.
  976          */
  977         if (((flags & FWRITE) == 0) || ((flags & FREAD) == 0))
  978                 return(EPERM);
  979 
  980         /*
  981          * We don't allow nonblocking access.
  982          */
  983         if ((flags & O_NONBLOCK) != 0) {
  984                 printf("%s: can't do nonblocking access\n", devtoname(dev));
  985                 return(ENODEV);
  986         }
  987 
  988         /* Mark ourselves open */
  989         mtx_lock(&xsoftc.xpt_lock);
  990         xsoftc.flags |= XPT_FLAG_OPEN;
  991         mtx_unlock(&xsoftc.xpt_lock);
  992 
  993         return(0);
  994 }
  995 
  996 static int
  997 xptclose(struct cdev *dev, int flag, int fmt, struct thread *td)
  998 {
  999 
 1000         /* Mark ourselves closed */
 1001         mtx_lock(&xsoftc.xpt_lock);
 1002         xsoftc.flags &= ~XPT_FLAG_OPEN;
 1003         mtx_unlock(&xsoftc.xpt_lock);
 1004 
 1005         return(0);
 1006 }
 1007 
 1008 /*
 1009  * Don't automatically grab the xpt softc lock here even though this is going
 1010  * through the xpt device.  The xpt device is really just a back door for
 1011  * accessing other devices and SIMs, so the right thing to do is to grab
 1012  * the appropriate SIM lock once the bus/SIM is located.
 1013  */
 1014 static int
 1015 xptioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td)
 1016 {
 1017         int error;
 1018 
 1019         error = 0;
 1020 
 1021         switch(cmd) {
 1022         /*
 1023          * For the transport layer CAMIOCOMMAND ioctl, we really only want
 1024          * to accept CCB types that don't quite make sense to send through a
 1025          * passthrough driver. XPT_PATH_INQ is an exception to this, as stated
 1026          * in the CAM spec.
 1027          */
 1028         case CAMIOCOMMAND: {
 1029                 union ccb *ccb;
 1030                 union ccb *inccb;
 1031                 struct cam_eb *bus;
 1032 
 1033                 inccb = (union ccb *)addr;
 1034 
 1035                 bus = xpt_find_bus(inccb->ccb_h.path_id);
 1036                 if (bus == NULL) {
 1037                         error = EINVAL;
 1038                         break;
 1039                 }
 1040 
 1041                 switch(inccb->ccb_h.func_code) {
 1042                 case XPT_SCAN_BUS:
 1043                 case XPT_RESET_BUS:
 1044                         if ((inccb->ccb_h.target_id != CAM_TARGET_WILDCARD)
 1045                          || (inccb->ccb_h.target_lun != CAM_LUN_WILDCARD)) {
 1046                                 error = EINVAL;
 1047                                 break;
 1048                         }
 1049                         /* FALLTHROUGH */
 1050                 case XPT_PATH_INQ:
 1051                 case XPT_ENG_INQ:
 1052                 case XPT_SCAN_LUN:
 1053 
 1054                         ccb = xpt_alloc_ccb();
 1055 
 1056                         CAM_SIM_LOCK(bus->sim);
 1057 
 1058                         /*
 1059                          * Create a path using the bus, target, and lun the
 1060                          * user passed in.
 1061                          */
 1062                         if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
 1063                                             inccb->ccb_h.path_id,
 1064                                             inccb->ccb_h.target_id,
 1065                                             inccb->ccb_h.target_lun) !=
 1066                                             CAM_REQ_CMP){
 1067                                 error = EINVAL;
 1068                                 CAM_SIM_UNLOCK(bus->sim);
 1069                                 xpt_free_ccb(ccb);
 1070                                 break;
 1071                         }
 1072                         /* Ensure all of our fields are correct */
 1073                         xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path,
 1074                                       inccb->ccb_h.pinfo.priority);
 1075                         xpt_merge_ccb(ccb, inccb);
 1076                         ccb->ccb_h.cbfcnp = xptdone;
 1077                         cam_periph_runccb(ccb, NULL, 0, 0, NULL);
 1078                         bcopy(ccb, inccb, sizeof(union ccb));
 1079                         xpt_free_path(ccb->ccb_h.path);
 1080                         xpt_free_ccb(ccb);
 1081                         CAM_SIM_UNLOCK(bus->sim);
 1082                         break;
 1083 
 1084                 case XPT_DEBUG: {
 1085                         union ccb ccb;
 1086 
 1087                         /*
 1088                          * This is an immediate CCB, so it's okay to
 1089                          * allocate it on the stack.
 1090                          */
 1091 
 1092                         CAM_SIM_LOCK(bus->sim);
 1093 
 1094                         /*
 1095                          * Create a path using the bus, target, and lun the
 1096                          * user passed in.
 1097                          */
 1098                         if (xpt_create_path(&ccb.ccb_h.path, xpt_periph,
 1099                                             inccb->ccb_h.path_id,
 1100                                             inccb->ccb_h.target_id,
 1101                                             inccb->ccb_h.target_lun) !=
 1102                                             CAM_REQ_CMP){
 1103                                 error = EINVAL;
 1104                                 CAM_SIM_UNLOCK(bus->sim);
 1105                                 break;
 1106                         }
 1107                         /* Ensure all of our fields are correct */
 1108                         xpt_setup_ccb(&ccb.ccb_h, ccb.ccb_h.path,
 1109                                       inccb->ccb_h.pinfo.priority);
 1110                         xpt_merge_ccb(&ccb, inccb);
 1111                         ccb.ccb_h.cbfcnp = xptdone;
 1112                         xpt_action(&ccb);
 1113                         CAM_SIM_UNLOCK(bus->sim);
 1114                         bcopy(&ccb, inccb, sizeof(union ccb));
 1115                         xpt_free_path(ccb.ccb_h.path);
 1116                         break;
 1117 
 1118                 }
 1119                 case XPT_DEV_MATCH: {
 1120                         struct cam_periph_map_info mapinfo;
 1121                         struct cam_path *old_path;
 1122 
 1123                         /*
 1124                          * We can't deal with physical addresses for this
 1125                          * type of transaction.
 1126                          */
 1127                         if (inccb->ccb_h.flags & CAM_DATA_PHYS) {
 1128                                 error = EINVAL;
 1129                                 break;
 1130                         }
 1131 
 1132                         /*
 1133                          * Save this in case the caller had it set to
 1134                          * something in particular.
 1135                          */
 1136                         old_path = inccb->ccb_h.path;
 1137 
 1138                         /*
 1139                          * We really don't need a path for the matching
 1140                          * code.  The path is needed because of the
 1141                          * debugging statements in xpt_action().  They
 1142                          * assume that the CCB has a valid path.
 1143                          */
 1144                         inccb->ccb_h.path = xpt_periph->path;
 1145 
 1146                         bzero(&mapinfo, sizeof(mapinfo));
 1147 
 1148                         /*
 1149                          * Map the pattern and match buffers into kernel
 1150                          * virtual address space.
 1151                          */
 1152                         error = cam_periph_mapmem(inccb, &mapinfo);
 1153 
 1154                         if (error) {
 1155                                 inccb->ccb_h.path = old_path;
 1156                                 break;
 1157                         }
 1158 
 1159                         /*
 1160                          * This is an immediate CCB, we can send it on directly.
 1161                          */
 1162                         xpt_action(inccb);
 1163 
 1164                         /*
 1165                          * Map the buffers back into user space.
 1166                          */
 1167                         cam_periph_unmapmem(inccb, &mapinfo);
 1168 
 1169                         inccb->ccb_h.path = old_path;
 1170 
 1171                         error = 0;
 1172                         break;
 1173                 }
 1174                 default:
 1175                         error = ENOTSUP;
 1176                         break;
 1177                 }
 1178                 xpt_release_bus(bus);
 1179                 break;
 1180         }
 1181         /*
 1182          * This is the getpassthru ioctl. It takes a XPT_GDEVLIST ccb as input,
 1183          * with the periphal driver name and unit name filled in.  The other
 1184          * fields don't really matter as input.  The passthrough driver name
 1185          * ("pass"), and unit number are passed back in the ccb.  The current
 1186          * device generation number, and the index into the device peripheral
 1187          * driver list, and the status are also passed back.  Note that
 1188          * since we do everything in one pass, unlike the XPT_GDEVLIST ccb,
 1189          * we never return a status of CAM_GDEVLIST_LIST_CHANGED.  It is
 1190          * (or rather should be) impossible for the device peripheral driver
 1191          * list to change since we look at the whole thing in one pass, and
 1192          * we do it with lock protection.
 1193          *
 1194          */
 1195         case CAMGETPASSTHRU: {
 1196                 union ccb *ccb;
 1197                 struct cam_periph *periph;
 1198                 struct periph_driver **p_drv;
 1199                 char   *name;
 1200                 u_int unit;
 1201                 u_int cur_generation;
 1202                 int base_periph_found;
 1203                 int splbreaknum;
 1204 
 1205                 ccb = (union ccb *)addr;
 1206                 unit = ccb->cgdl.unit_number;
 1207                 name = ccb->cgdl.periph_name;
 1208                 /*
 1209                  * Every 100 devices, we want to drop our lock protection to
 1210                  * give the software interrupt handler a chance to run.
 1211                  * Most systems won't run into this check, but this should
 1212                  * avoid starvation in the software interrupt handler in
 1213                  * large systems.
 1214                  */
 1215                 splbreaknum = 100;
 1216 
 1217                 ccb = (union ccb *)addr;
 1218 
 1219                 base_periph_found = 0;
 1220 
 1221                 /*
 1222                  * Sanity check -- make sure we don't get a null peripheral
 1223                  * driver name.
 1224                  */
 1225                 if (*ccb->cgdl.periph_name == '\0') {
 1226                         error = EINVAL;
 1227                         break;
 1228                 }
 1229 
 1230                 /* Keep the list from changing while we traverse it */
 1231                 mtx_lock(&xsoftc.xpt_topo_lock);
 1232 ptstartover:
 1233                 cur_generation = xsoftc.xpt_generation;
 1234 
 1235                 /* first find our driver in the list of drivers */
 1236                 for (p_drv = periph_drivers; *p_drv != NULL; p_drv++)
 1237                         if (strcmp((*p_drv)->driver_name, name) == 0)
 1238                                 break;
 1239 
 1240                 if (*p_drv == NULL) {
 1241                         mtx_unlock(&xsoftc.xpt_topo_lock);
 1242                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 1243                         ccb->cgdl.status = CAM_GDEVLIST_ERROR;
 1244                         *ccb->cgdl.periph_name = '\0';
 1245                         ccb->cgdl.unit_number = 0;
 1246                         error = ENOENT;
 1247                         break;
 1248                 }
 1249 
 1250                 /*
 1251                  * Run through every peripheral instance of this driver
 1252                  * and check to see whether it matches the unit passed
 1253                  * in by the user.  If it does, get out of the loops and
 1254                  * find the passthrough driver associated with that
 1255                  * peripheral driver.
 1256                  */
 1257                 for (periph = TAILQ_FIRST(&(*p_drv)->units); periph != NULL;
 1258                      periph = TAILQ_NEXT(periph, unit_links)) {
 1259 
 1260                         if (periph->unit_number == unit) {
 1261                                 break;
 1262                         } else if (--splbreaknum == 0) {
 1263                                 mtx_unlock(&xsoftc.xpt_topo_lock);
 1264                                 mtx_lock(&xsoftc.xpt_topo_lock);
 1265                                 splbreaknum = 100;
 1266                                 if (cur_generation != xsoftc.xpt_generation)
 1267                                        goto ptstartover;
 1268                         }
 1269                 }
 1270                 /*
 1271                  * If we found the peripheral driver that the user passed
 1272                  * in, go through all of the peripheral drivers for that
 1273                  * particular device and look for a passthrough driver.
 1274                  */
 1275                 if (periph != NULL) {
 1276                         struct cam_ed *device;
 1277                         int i;
 1278 
 1279                         base_periph_found = 1;
 1280                         device = periph->path->device;
 1281                         for (i = 0, periph = SLIST_FIRST(&device->periphs);
 1282                              periph != NULL;
 1283                              periph = SLIST_NEXT(periph, periph_links), i++) {
 1284                                 /*
 1285                                  * Check to see whether we have a
 1286                                  * passthrough device or not.
 1287                                  */
 1288                                 if (strcmp(periph->periph_name, "pass") == 0) {
 1289                                         /*
 1290                                          * Fill in the getdevlist fields.
 1291                                          */
 1292                                         strcpy(ccb->cgdl.periph_name,
 1293                                                periph->periph_name);
 1294                                         ccb->cgdl.unit_number =
 1295                                                 periph->unit_number;
 1296                                         if (SLIST_NEXT(periph, periph_links))
 1297                                                 ccb->cgdl.status =
 1298                                                         CAM_GDEVLIST_MORE_DEVS;
 1299                                         else
 1300                                                 ccb->cgdl.status =
 1301                                                        CAM_GDEVLIST_LAST_DEVICE;
 1302                                         ccb->cgdl.generation =
 1303                                                 device->generation;
 1304                                         ccb->cgdl.index = i;
 1305                                         /*
 1306                                          * Fill in some CCB header fields
 1307                                          * that the user may want.
 1308                                          */
 1309                                         ccb->ccb_h.path_id =
 1310                                                 periph->path->bus->path_id;
 1311                                         ccb->ccb_h.target_id =
 1312                                                 periph->path->target->target_id;
 1313                                         ccb->ccb_h.target_lun =
 1314                                                 periph->path->device->lun_id;
 1315                                         ccb->ccb_h.status = CAM_REQ_CMP;
 1316                                         break;
 1317                                 }
 1318                         }
 1319                 }
 1320 
 1321                 /*
 1322                  * If the periph is null here, one of two things has
 1323                  * happened.  The first possibility is that we couldn't
 1324                  * find the unit number of the particular peripheral driver
 1325                  * that the user is asking about.  e.g. the user asks for
 1326                  * the passthrough driver for "da11".  We find the list of
 1327                  * "da" peripherals all right, but there is no unit 11.
 1328                  * The other possibility is that we went through the list
 1329                  * of peripheral drivers attached to the device structure,
 1330                  * but didn't find one with the name "pass".  Either way,
 1331                  * we return ENOENT, since we couldn't find something.
 1332                  */
 1333                 if (periph == NULL) {
 1334                         ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 1335                         ccb->cgdl.status = CAM_GDEVLIST_ERROR;
 1336                         *ccb->cgdl.periph_name = '\0';
 1337                         ccb->cgdl.unit_number = 0;
 1338                         error = ENOENT;
 1339                         /*
 1340                          * It is unfortunate that this is even necessary,
 1341                          * but there are many, many clueless users out there.
 1342                          * If this is true, the user is looking for the
 1343                          * passthrough driver, but doesn't have one in his
 1344                          * kernel.
 1345                          */
 1346                         if (base_periph_found == 1) {
 1347                                 printf("xptioctl: pass driver is not in the "
 1348                                        "kernel\n");
 1349                                 printf("xptioctl: put \"device pass\" in "
 1350                                        "your kernel config file\n");
 1351                         }
 1352                 }
 1353                 mtx_unlock(&xsoftc.xpt_topo_lock);
 1354                 break;
 1355                 }
 1356         default:
 1357                 error = ENOTTY;
 1358                 break;
 1359         }
 1360 
 1361         return(error);
 1362 }
 1363 
 1364 static int
 1365 cam_module_event_handler(module_t mod, int what, void *arg)
 1366 {
 1367         int error;
 1368 
 1369         switch (what) {
 1370         case MOD_LOAD:
 1371                 if ((error = xpt_init(NULL)) != 0)
 1372                         return (error);
 1373                 break;
 1374         case MOD_UNLOAD:
 1375                 return EBUSY;
 1376         default:
 1377                 return EOPNOTSUPP;
 1378         }
 1379 
 1380         return 0;
 1381 }
 1382 
 1383 /* thread to handle bus rescans */
 1384 static void
 1385 xpt_scanner_thread(void *dummy)
 1386 {
 1387         cam_isrq_t      queue;
 1388         union ccb       *ccb;
 1389         struct cam_sim  *sim;
 1390 
 1391         for (;;) {
 1392                 /*
 1393                  * Wait for a rescan request to come in.  When it does, splice
 1394                  * it onto a queue from local storage so that the xpt lock
 1395                  * doesn't need to be held while the requests are being
 1396                  * processed.
 1397                  */
 1398                 xpt_lock_buses();
 1399                 msleep(&xsoftc.ccb_scanq, &xsoftc.xpt_topo_lock, PRIBIO,
 1400                     "ccb_scanq", 0);
 1401                 TAILQ_INIT(&queue);
 1402                 TAILQ_CONCAT(&queue, &xsoftc.ccb_scanq, sim_links.tqe);
 1403                 xpt_unlock_buses();
 1404 
 1405                 while ((ccb = (union ccb *)TAILQ_FIRST(&queue)) != NULL) {
 1406                         TAILQ_REMOVE(&queue, &ccb->ccb_h, sim_links.tqe);
 1407 
 1408                         sim = ccb->ccb_h.path->bus->sim;
 1409                         CAM_SIM_LOCK(sim);
 1410 
 1411                         ccb->ccb_h.func_code = XPT_SCAN_BUS;
 1412                         ccb->ccb_h.cbfcnp = xptdone;
 1413                         xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 5);
 1414                         cam_periph_runccb(ccb, NULL, 0, 0, NULL);
 1415                         xpt_free_path(ccb->ccb_h.path);
 1416                         xpt_free_ccb(ccb);
 1417                         CAM_SIM_UNLOCK(sim);
 1418                 }
 1419         }
 1420 }
 1421 
 1422 void
 1423 xpt_rescan(union ccb *ccb)
 1424 {
 1425         struct ccb_hdr *hdr;
 1426 
 1427         /*
 1428          * Don't make duplicate entries for the same paths.
 1429          */
 1430         xpt_lock_buses();
 1431         TAILQ_FOREACH(hdr, &xsoftc.ccb_scanq, sim_links.tqe) {
 1432                 if (xpt_path_comp(hdr->path, ccb->ccb_h.path) == 0) {
 1433                         xpt_unlock_buses();
 1434                         xpt_print(ccb->ccb_h.path, "rescan already queued\n");
 1435                         xpt_free_path(ccb->ccb_h.path);
 1436                         xpt_free_ccb(ccb);
 1437                         return;
 1438                 }
 1439         }
 1440         TAILQ_INSERT_TAIL(&xsoftc.ccb_scanq, &ccb->ccb_h, sim_links.tqe);
 1441         wakeup(&xsoftc.ccb_scanq);
 1442         xpt_unlock_buses();
 1443 }
 1444 
 1445 /* Functions accessed by the peripheral drivers */
 1446 static int
 1447 xpt_init(void *dummy)
 1448 {
 1449         struct cam_sim *xpt_sim;
 1450         struct cam_path *path;
 1451         struct cam_devq *devq;
 1452         cam_status status;
 1453 
 1454         TAILQ_INIT(&xsoftc.xpt_busses);
 1455         TAILQ_INIT(&cam_simq);
 1456         TAILQ_INIT(&xsoftc.ccb_scanq);
 1457         STAILQ_INIT(&xsoftc.highpowerq);
 1458         xsoftc.num_highpower = CAM_MAX_HIGHPOWER;
 1459 
 1460         mtx_init(&cam_simq_lock, "CAM SIMQ lock", NULL, MTX_DEF);
 1461         mtx_init(&xsoftc.xpt_lock, "XPT lock", NULL, MTX_DEF);
 1462         mtx_init(&xsoftc.xpt_topo_lock, "XPT topology lock", NULL, MTX_DEF);
 1463 
 1464         /*
 1465          * The xpt layer is, itself, the equivelent of a SIM.
 1466          * Allow 16 ccbs in the ccb pool for it.  This should
 1467          * give decent parallelism when we probe busses and
 1468          * perform other XPT functions.
 1469          */
 1470         devq = cam_simq_alloc(16);
 1471         xpt_sim = cam_sim_alloc(xptaction,
 1472                                 xptpoll,
 1473                                 "xpt",
 1474                                 /*softc*/NULL,
 1475                                 /*unit*/0,
 1476                                 /*mtx*/&xsoftc.xpt_lock,
 1477                                 /*max_dev_transactions*/0,
 1478                                 /*max_tagged_dev_transactions*/0,
 1479                                 devq);
 1480         if (xpt_sim == NULL)
 1481                 return (ENOMEM);
 1482 
 1483         xpt_sim->max_ccbs = 16;
 1484 
 1485         mtx_lock(&xsoftc.xpt_lock);
 1486         if ((status = xpt_bus_register(xpt_sim, NULL, 0)) != CAM_SUCCESS) {
 1487                 printf("xpt_init: xpt_bus_register failed with status %#x,"
 1488                        " failing attach\n", status);
 1489                 return (EINVAL);
 1490         }
 1491 
 1492         /*
 1493          * Looking at the XPT from the SIM layer, the XPT is
 1494          * the equivelent of a peripheral driver.  Allocate
 1495          * a peripheral driver entry for us.
 1496          */
 1497         if ((status = xpt_create_path(&path, NULL, CAM_XPT_PATH_ID,
 1498                                       CAM_TARGET_WILDCARD,
 1499                                       CAM_LUN_WILDCARD)) != CAM_REQ_CMP) {
 1500                 printf("xpt_init: xpt_create_path failed with status %#x,"
 1501                        " failing attach\n", status);
 1502                 return (EINVAL);
 1503         }
 1504 
 1505         cam_periph_alloc(xptregister, NULL, NULL, NULL, "xpt", CAM_PERIPH_BIO,
 1506                          path, NULL, 0, xpt_sim);
 1507         xpt_free_path(path);
 1508         mtx_unlock(&xsoftc.xpt_lock);
 1509 
 1510         /*
 1511          * Register a callback for when interrupts are enabled.
 1512          */
 1513         xsoftc.xpt_config_hook =
 1514             (struct intr_config_hook *)malloc(sizeof(struct intr_config_hook),
 1515                                               M_CAMXPT, M_NOWAIT | M_ZERO);
 1516         if (xsoftc.xpt_config_hook == NULL) {
 1517                 printf("xpt_init: Cannot malloc config hook "
 1518                        "- failing attach\n");
 1519                 return (ENOMEM);
 1520         }
 1521 
 1522         xsoftc.xpt_config_hook->ich_func = xpt_config;
 1523         if (config_intrhook_establish(xsoftc.xpt_config_hook) != 0) {
 1524                 free (xsoftc.xpt_config_hook, M_CAMXPT);
 1525                 printf("xpt_init: config_intrhook_establish failed "
 1526                        "- failing attach\n");
 1527         }
 1528 
 1529         /* fire up rescan thread */
 1530         if (kthread_create(xpt_scanner_thread, NULL, NULL, 0, 0, "xpt_thrd")) {
 1531                 printf("xpt_init: failed to create rescan thread\n");
 1532         }
 1533         /* Install our software interrupt handlers */
 1534         swi_add(NULL, "cambio", camisr, NULL, SWI_CAMBIO, INTR_MPSAFE, &cambio_ih);
 1535 
 1536         return (0);
 1537 }
 1538 
 1539 static cam_status
 1540 xptregister(struct cam_periph *periph, void *arg)
 1541 {
 1542         struct cam_sim *xpt_sim;
 1543 
 1544         if (periph == NULL) {
 1545                 printf("xptregister: periph was NULL!!\n");
 1546                 return(CAM_REQ_CMP_ERR);
 1547         }
 1548 
 1549         xpt_sim = (struct cam_sim *)arg;
 1550         xpt_sim->softc = periph;
 1551         xpt_periph = periph;
 1552         periph->softc = NULL;
 1553 
 1554         return(CAM_REQ_CMP);
 1555 }
 1556 
 1557 int32_t
 1558 xpt_add_periph(struct cam_periph *periph)
 1559 {
 1560         struct cam_ed *device;
 1561         int32_t  status;
 1562         struct periph_list *periph_head;
 1563 
 1564         mtx_assert(periph->sim->mtx, MA_OWNED);
 1565 
 1566         device = periph->path->device;
 1567 
 1568         periph_head = &device->periphs;
 1569 
 1570         status = CAM_REQ_CMP;
 1571 
 1572         if (device != NULL) {
 1573                 /*
 1574                  * Make room for this peripheral
 1575                  * so it will fit in the queue
 1576                  * when it's scheduled to run
 1577                  */
 1578                 status = camq_resize(&device->drvq,
 1579                                      device->drvq.array_size + 1);
 1580 
 1581                 device->generation++;
 1582 
 1583                 SLIST_INSERT_HEAD(periph_head, periph, periph_links);
 1584         }
 1585 
 1586         mtx_lock(&xsoftc.xpt_topo_lock);
 1587         xsoftc.xpt_generation++;
 1588         mtx_unlock(&xsoftc.xpt_topo_lock);
 1589 
 1590         return (status);
 1591 }
 1592 
 1593 void
 1594 xpt_remove_periph(struct cam_periph *periph)
 1595 {
 1596         struct cam_ed *device;
 1597 
 1598         mtx_assert(periph->sim->mtx, MA_OWNED);
 1599 
 1600         device = periph->path->device;
 1601 
 1602         if (device != NULL) {
 1603                 struct periph_list *periph_head;
 1604 
 1605                 periph_head = &device->periphs;
 1606 
 1607                 /* Release the slot for this peripheral */
 1608                 camq_resize(&device->drvq, device->drvq.array_size - 1);
 1609 
 1610                 device->generation++;
 1611 
 1612                 SLIST_REMOVE(periph_head, periph, cam_periph, periph_links);
 1613         }
 1614 
 1615         mtx_lock(&xsoftc.xpt_topo_lock);
 1616         xsoftc.xpt_generation++;
 1617         mtx_unlock(&xsoftc.xpt_topo_lock);
 1618 }
 1619 
 1620 
 1621 void
 1622 xpt_announce_periph(struct cam_periph *periph, char *announce_string)
 1623 {
 1624         struct  ccb_pathinq cpi;
 1625         struct  ccb_trans_settings cts;
 1626         struct  cam_path *path;
 1627         u_int   speed;
 1628         u_int   freq;
 1629         u_int   mb;
 1630 
 1631         mtx_assert(periph->sim->mtx, MA_OWNED);
 1632 
 1633         path = periph->path;
 1634         /*
 1635          * To ensure that this is printed in one piece,
 1636          * mask out CAM interrupts.
 1637          */
 1638         printf("%s%d at %s%d bus %d target %d lun %d\n",
 1639                periph->periph_name, periph->unit_number,
 1640                path->bus->sim->sim_name,
 1641                path->bus->sim->unit_number,
 1642                path->bus->sim->bus_id,
 1643                path->target->target_id,
 1644                path->device->lun_id);
 1645         printf("%s%d: ", periph->periph_name, periph->unit_number);
 1646         scsi_print_inquiry(&path->device->inq_data);
 1647         if (bootverbose && path->device->serial_num_len > 0) {
 1648                 /* Don't wrap the screen  - print only the first 60 chars */
 1649                 printf("%s%d: Serial Number %.60s\n", periph->periph_name,
 1650                        periph->unit_number, path->device->serial_num);
 1651         }
 1652         xpt_setup_ccb(&cts.ccb_h, path, /*priority*/1);
 1653         cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 1654         cts.type = CTS_TYPE_CURRENT_SETTINGS;
 1655         xpt_action((union ccb*)&cts);
 1656         if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 1657                 return;
 1658         }
 1659 
 1660         /* Ask the SIM for its base transfer speed */
 1661         xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
 1662         cpi.ccb_h.func_code = XPT_PATH_INQ;
 1663         xpt_action((union ccb *)&cpi);
 1664 
 1665         speed = cpi.base_transfer_speed;
 1666         freq = 0;
 1667         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) {
 1668                 struct  ccb_trans_settings_spi *spi;
 1669 
 1670                 spi = &cts.xport_specific.spi;
 1671                 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0
 1672                   && spi->sync_offset != 0) {
 1673                         freq = scsi_calc_syncsrate(spi->sync_period);
 1674                         speed = freq;
 1675                 }
 1676 
 1677                 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
 1678                         speed *= (0x01 << spi->bus_width);
 1679         }
 1680 
 1681         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) {
 1682                 struct  ccb_trans_settings_fc *fc = &cts.xport_specific.fc;
 1683                 if (fc->valid & CTS_FC_VALID_SPEED) {
 1684                         speed = fc->bitrate;
 1685                 }
 1686         }
 1687 
 1688         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SAS) {
 1689                 struct  ccb_trans_settings_sas *sas = &cts.xport_specific.sas;
 1690                 if (sas->valid & CTS_SAS_VALID_SPEED) {
 1691                         speed = sas->bitrate;
 1692                 }
 1693         }
 1694 
 1695         mb = speed / 1000;
 1696         if (mb > 0)
 1697                 printf("%s%d: %d.%03dMB/s transfers",
 1698                        periph->periph_name, periph->unit_number,
 1699                        mb, speed % 1000);
 1700         else
 1701                 printf("%s%d: %dKB/s transfers", periph->periph_name,
 1702                        periph->unit_number, speed);
 1703         /* Report additional information about SPI connections */
 1704         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) {
 1705                 struct  ccb_trans_settings_spi *spi;
 1706 
 1707                 spi = &cts.xport_specific.spi;
 1708                 if (freq != 0) {
 1709                         printf(" (%d.%03dMHz%s, offset %d", freq / 1000,
 1710                                freq % 1000,
 1711                                (spi->ppr_options & MSG_EXT_PPR_DT_REQ) != 0
 1712                              ? " DT" : "",
 1713                                spi->sync_offset);
 1714                 }
 1715                 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0
 1716                  && spi->bus_width > 0) {
 1717                         if (freq != 0) {
 1718                                 printf(", ");
 1719                         } else {
 1720                                 printf(" (");
 1721                         }
 1722                         printf("%dbit)", 8 * (0x01 << spi->bus_width));
 1723                 } else if (freq != 0) {
 1724                         printf(")");
 1725                 }
 1726         }
 1727         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) {
 1728                 struct  ccb_trans_settings_fc *fc;
 1729 
 1730                 fc = &cts.xport_specific.fc;
 1731                 if (fc->valid & CTS_FC_VALID_WWNN)
 1732                         printf(" WWNN 0x%llx", (long long) fc->wwnn);
 1733                 if (fc->valid & CTS_FC_VALID_WWPN)
 1734                         printf(" WWPN 0x%llx", (long long) fc->wwpn);
 1735                 if (fc->valid & CTS_FC_VALID_PORT)
 1736                         printf(" PortID 0x%x", fc->port);
 1737         }
 1738 
 1739         if (path->device->inq_flags & SID_CmdQue
 1740          || path->device->flags & CAM_DEV_TAG_AFTER_COUNT) {
 1741                 printf("\n%s%d: Command Queueing Enabled",
 1742                        periph->periph_name, periph->unit_number);
 1743         }
 1744         printf("\n");
 1745 
 1746         /*
 1747          * We only want to print the caller's announce string if they've
 1748          * passed one in..
 1749          */
 1750         if (announce_string != NULL)
 1751                 printf("%s%d: %s\n", periph->periph_name,
 1752                        periph->unit_number, announce_string);
 1753 }
 1754 
 1755 static dev_match_ret
 1756 xptbusmatch(struct dev_match_pattern *patterns, u_int num_patterns,
 1757             struct cam_eb *bus)
 1758 {
 1759         dev_match_ret retval;
 1760         int i;
 1761 
 1762         retval = DM_RET_NONE;
 1763 
 1764         /*
 1765          * If we aren't given something to match against, that's an error.
 1766          */
 1767         if (bus == NULL)
 1768                 return(DM_RET_ERROR);
 1769 
 1770         /*
 1771          * If there are no match entries, then this bus matches no
 1772          * matter what.
 1773          */
 1774         if ((patterns == NULL) || (num_patterns == 0))
 1775                 return(DM_RET_DESCEND | DM_RET_COPY);
 1776 
 1777         for (i = 0; i < num_patterns; i++) {
 1778                 struct bus_match_pattern *cur_pattern;
 1779 
 1780                 /*
 1781                  * If the pattern in question isn't for a bus node, we
 1782                  * aren't interested.  However, we do indicate to the
 1783                  * calling routine that we should continue descending the
 1784                  * tree, since the user wants to match against lower-level
 1785                  * EDT elements.
 1786                  */
 1787                 if (patterns[i].type != DEV_MATCH_BUS) {
 1788                         if ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE)
 1789                                 retval |= DM_RET_DESCEND;
 1790                         continue;
 1791                 }
 1792 
 1793                 cur_pattern = &patterns[i].pattern.bus_pattern;
 1794 
 1795                 /*
 1796                  * If they want to match any bus node, we give them any
 1797                  * device node.
 1798                  */
 1799                 if (cur_pattern->flags == BUS_MATCH_ANY) {
 1800                         /* set the copy flag */
 1801                         retval |= DM_RET_COPY;
 1802 
 1803                         /*
 1804                          * If we've already decided on an action, go ahead
 1805                          * and return.
 1806                          */
 1807                         if ((retval & DM_RET_ACTION_MASK) != DM_RET_NONE)
 1808                                 return(retval);
 1809                 }
 1810 
 1811                 /*
 1812                  * Not sure why someone would do this...
 1813                  */
 1814                 if (cur_pattern->flags == BUS_MATCH_NONE)
 1815                         continue;
 1816 
 1817                 if (((cur_pattern->flags & BUS_MATCH_PATH) != 0)
 1818                  && (cur_pattern->path_id != bus->path_id))
 1819                         continue;
 1820 
 1821                 if (((cur_pattern->flags & BUS_MATCH_BUS_ID) != 0)
 1822                  && (cur_pattern->bus_id != bus->sim->bus_id))
 1823                         continue;
 1824 
 1825                 if (((cur_pattern->flags & BUS_MATCH_UNIT) != 0)
 1826                  && (cur_pattern->unit_number != bus->sim->unit_number))
 1827                         continue;
 1828 
 1829                 if (((cur_pattern->flags & BUS_MATCH_NAME) != 0)
 1830                  && (strncmp(cur_pattern->dev_name, bus->sim->sim_name,
 1831                              DEV_IDLEN) != 0))
 1832                         continue;
 1833 
 1834                 /*
 1835                  * If we get to this point, the user definitely wants
 1836                  * information on this bus.  So tell the caller to copy the
 1837                  * data out.
 1838                  */
 1839                 retval |= DM_RET_COPY;
 1840 
 1841                 /*
 1842                  * If the return action has been set to descend, then we
 1843                  * know that we've already seen a non-bus matching
 1844                  * expression, therefore we need to further descend the tree.
 1845                  * This won't change by continuing around the loop, so we
 1846                  * go ahead and return.  If we haven't seen a non-bus
 1847                  * matching expression, we keep going around the loop until
 1848                  * we exhaust the matching expressions.  We'll set the stop
 1849                  * flag once we fall out of the loop.
 1850                  */
 1851                 if ((retval & DM_RET_ACTION_MASK) == DM_RET_DESCEND)
 1852                         return(retval);
 1853         }
 1854 
 1855         /*
 1856          * If the return action hasn't been set to descend yet, that means
 1857          * we haven't seen anything other than bus matching patterns.  So
 1858          * tell the caller to stop descending the tree -- the user doesn't
 1859          * want to match against lower level tree elements.
 1860          */
 1861         if ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE)
 1862                 retval |= DM_RET_STOP;
 1863 
 1864         return(retval);
 1865 }
 1866 
 1867 static dev_match_ret
 1868 xptdevicematch(struct dev_match_pattern *patterns, u_int num_patterns,
 1869                struct cam_ed *device)
 1870 {
 1871         dev_match_ret retval;
 1872         int i;
 1873 
 1874         retval = DM_RET_NONE;
 1875 
 1876         /*
 1877          * If we aren't given something to match against, that's an error.
 1878          */
 1879         if (device == NULL)
 1880                 return(DM_RET_ERROR);
 1881 
 1882         /*
 1883          * If there are no match entries, then this device matches no
 1884          * matter what.
 1885          */
 1886         if ((patterns == NULL) || (num_patterns == 0))
 1887                 return(DM_RET_DESCEND | DM_RET_COPY);
 1888 
 1889         for (i = 0; i < num_patterns; i++) {
 1890                 struct device_match_pattern *cur_pattern;
 1891 
 1892                 /*
 1893                  * If the pattern in question isn't for a device node, we
 1894                  * aren't interested.
 1895                  */
 1896                 if (patterns[i].type != DEV_MATCH_DEVICE) {
 1897                         if ((patterns[i].type == DEV_MATCH_PERIPH)
 1898                          && ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE))
 1899                                 retval |= DM_RET_DESCEND;
 1900                         continue;
 1901                 }
 1902 
 1903                 cur_pattern = &patterns[i].pattern.device_pattern;
 1904 
 1905                 /*
 1906                  * If they want to match any device node, we give them any
 1907                  * device node.
 1908                  */
 1909                 if (cur_pattern->flags == DEV_MATCH_ANY) {
 1910                         /* set the copy flag */
 1911                         retval |= DM_RET_COPY;
 1912 
 1913 
 1914                         /*
 1915                          * If we've already decided on an action, go ahead
 1916                          * and return.
 1917                          */
 1918                         if ((retval & DM_RET_ACTION_MASK) != DM_RET_NONE)
 1919                                 return(retval);
 1920                 }
 1921 
 1922                 /*
 1923                  * Not sure why someone would do this...
 1924                  */
 1925                 if (cur_pattern->flags == DEV_MATCH_NONE)
 1926                         continue;
 1927 
 1928                 if (((cur_pattern->flags & DEV_MATCH_PATH) != 0)
 1929                  && (cur_pattern->path_id != device->target->bus->path_id))
 1930                         continue;
 1931 
 1932                 if (((cur_pattern->flags & DEV_MATCH_TARGET) != 0)
 1933                  && (cur_pattern->target_id != device->target->target_id))
 1934                         continue;
 1935 
 1936                 if (((cur_pattern->flags & DEV_MATCH_LUN) != 0)
 1937                  && (cur_pattern->target_lun != device->lun_id))
 1938                         continue;
 1939 
 1940                 if (((cur_pattern->flags & DEV_MATCH_INQUIRY) != 0)
 1941                  && (cam_quirkmatch((caddr_t)&device->inq_data,
 1942                                     (caddr_t)&cur_pattern->inq_pat,
 1943                                     1, sizeof(cur_pattern->inq_pat),
 1944                                     scsi_static_inquiry_match) == NULL))
 1945                         continue;
 1946 
 1947                 /*
 1948                  * If we get to this point, the user definitely wants
 1949                  * information on this device.  So tell the caller to copy
 1950                  * the data out.
 1951                  */
 1952                 retval |= DM_RET_COPY;
 1953 
 1954                 /*
 1955                  * If the return action has been set to descend, then we
 1956                  * know that we've already seen a peripheral matching
 1957                  * expression, therefore we need to further descend the tree.
 1958                  * This won't change by continuing around the loop, so we
 1959                  * go ahead and return.  If we haven't seen a peripheral
 1960                  * matching expression, we keep going around the loop until
 1961                  * we exhaust the matching expressions.  We'll set the stop
 1962                  * flag once we fall out of the loop.
 1963                  */
 1964                 if ((retval & DM_RET_ACTION_MASK) == DM_RET_DESCEND)
 1965                         return(retval);
 1966         }
 1967 
 1968         /*
 1969          * If the return action hasn't been set to descend yet, that means
 1970          * we haven't seen any peripheral matching patterns.  So tell the
 1971          * caller to stop descending the tree -- the user doesn't want to
 1972          * match against lower level tree elements.
 1973          */
 1974         if ((retval & DM_RET_ACTION_MASK) == DM_RET_NONE)
 1975                 retval |= DM_RET_STOP;
 1976 
 1977         return(retval);
 1978 }
 1979 
 1980 /*
 1981  * Match a single peripheral against any number of match patterns.
 1982  */
 1983 static dev_match_ret
 1984 xptperiphmatch(struct dev_match_pattern *patterns, u_int num_patterns,
 1985                struct cam_periph *periph)
 1986 {
 1987         dev_match_ret retval;
 1988         int i;
 1989 
 1990         /*
 1991          * If we aren't given something to match against, that's an error.
 1992          */
 1993         if (periph == NULL)
 1994                 return(DM_RET_ERROR);
 1995 
 1996         /*
 1997          * If there are no match entries, then this peripheral matches no
 1998          * matter what.
 1999          */
 2000         if ((patterns == NULL) || (num_patterns == 0))
 2001                 return(DM_RET_STOP | DM_RET_COPY);
 2002 
 2003         /*
 2004          * There aren't any nodes below a peripheral node, so there's no
 2005          * reason to descend the tree any further.
 2006          */
 2007         retval = DM_RET_STOP;
 2008 
 2009         for (i = 0; i < num_patterns; i++) {
 2010                 struct periph_match_pattern *cur_pattern;
 2011 
 2012                 /*
 2013                  * If the pattern in question isn't for a peripheral, we
 2014                  * aren't interested.
 2015                  */
 2016                 if (patterns[i].type != DEV_MATCH_PERIPH)
 2017                         continue;
 2018 
 2019                 cur_pattern = &patterns[i].pattern.periph_pattern;
 2020 
 2021                 /*
 2022                  * If they want to match on anything, then we will do so.
 2023                  */
 2024                 if (cur_pattern->flags == PERIPH_MATCH_ANY) {
 2025                         /* set the copy flag */
 2026                         retval |= DM_RET_COPY;
 2027 
 2028                         /*
 2029                          * We've already set the return action to stop,
 2030                          * since there are no nodes below peripherals in
 2031                          * the tree.
 2032                          */
 2033                         return(retval);
 2034                 }
 2035 
 2036                 /*
 2037                  * Not sure why someone would do this...
 2038                  */
 2039                 if (cur_pattern->flags == PERIPH_MATCH_NONE)
 2040                         continue;
 2041 
 2042                 if (((cur_pattern->flags & PERIPH_MATCH_PATH) != 0)
 2043                  && (cur_pattern->path_id != periph->path->bus->path_id))
 2044                         continue;
 2045 
 2046                 /*
 2047                  * For the target and lun id's, we have to make sure the
 2048                  * target and lun pointers aren't NULL.  The xpt peripheral
 2049                  * has a wildcard target and device.
 2050                  */
 2051                 if (((cur_pattern->flags & PERIPH_MATCH_TARGET) != 0)
 2052                  && ((periph->path->target == NULL)
 2053                  ||(cur_pattern->target_id != periph->path->target->target_id)))
 2054                         continue;
 2055 
 2056                 if (((cur_pattern->flags & PERIPH_MATCH_LUN) != 0)
 2057                  && ((periph->path->device == NULL)
 2058                  || (cur_pattern->target_lun != periph->path->device->lun_id)))
 2059                         continue;
 2060 
 2061                 if (((cur_pattern->flags & PERIPH_MATCH_UNIT) != 0)
 2062                  && (cur_pattern->unit_number != periph->unit_number))
 2063                         continue;
 2064 
 2065                 if (((cur_pattern->flags & PERIPH_MATCH_NAME) != 0)
 2066                  && (strncmp(cur_pattern->periph_name, periph->periph_name,
 2067                              DEV_IDLEN) != 0))
 2068                         continue;
 2069 
 2070                 /*
 2071                  * If we get to this point, the user definitely wants
 2072                  * information on this peripheral.  So tell the caller to
 2073                  * copy the data out.
 2074                  */
 2075                 retval |= DM_RET_COPY;
 2076 
 2077                 /*
 2078                  * The return action has already been set to stop, since
 2079                  * peripherals don't have any nodes below them in the EDT.
 2080                  */
 2081                 return(retval);
 2082         }
 2083 
 2084         /*
 2085          * If we get to this point, the peripheral that was passed in
 2086          * doesn't match any of the patterns.
 2087          */
 2088         return(retval);
 2089 }
 2090 
 2091 static int
 2092 xptedtbusfunc(struct cam_eb *bus, void *arg)
 2093 {
 2094         struct ccb_dev_match *cdm;
 2095         dev_match_ret retval;
 2096 
 2097         cdm = (struct ccb_dev_match *)arg;
 2098 
 2099         /*
 2100          * If our position is for something deeper in the tree, that means
 2101          * that we've already seen this node.  So, we keep going down.
 2102          */
 2103         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 2104          && (cdm->pos.cookie.bus == bus)
 2105          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 2106          && (cdm->pos.cookie.target != NULL))
 2107                 retval = DM_RET_DESCEND;
 2108         else
 2109                 retval = xptbusmatch(cdm->patterns, cdm->num_patterns, bus);
 2110 
 2111         /*
 2112          * If we got an error, bail out of the search.
 2113          */
 2114         if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
 2115                 cdm->status = CAM_DEV_MATCH_ERROR;
 2116                 return(0);
 2117         }
 2118 
 2119         /*
 2120          * If the copy flag is set, copy this bus out.
 2121          */
 2122         if (retval & DM_RET_COPY) {
 2123                 int spaceleft, j;
 2124 
 2125                 spaceleft = cdm->match_buf_len - (cdm->num_matches *
 2126                         sizeof(struct dev_match_result));
 2127 
 2128                 /*
 2129                  * If we don't have enough space to put in another
 2130                  * match result, save our position and tell the
 2131                  * user there are more devices to check.
 2132                  */
 2133                 if (spaceleft < sizeof(struct dev_match_result)) {
 2134                         bzero(&cdm->pos, sizeof(cdm->pos));
 2135                         cdm->pos.position_type =
 2136                                 CAM_DEV_POS_EDT | CAM_DEV_POS_BUS;
 2137 
 2138                         cdm->pos.cookie.bus = bus;
 2139                         cdm->pos.generations[CAM_BUS_GENERATION]=
 2140                                 xsoftc.bus_generation;
 2141                         cdm->status = CAM_DEV_MATCH_MORE;
 2142                         return(0);
 2143                 }
 2144                 j = cdm->num_matches;
 2145                 cdm->num_matches++;
 2146                 cdm->matches[j].type = DEV_MATCH_BUS;
 2147                 cdm->matches[j].result.bus_result.path_id = bus->path_id;
 2148                 cdm->matches[j].result.bus_result.bus_id = bus->sim->bus_id;
 2149                 cdm->matches[j].result.bus_result.unit_number =
 2150                         bus->sim->unit_number;
 2151                 strncpy(cdm->matches[j].result.bus_result.dev_name,
 2152                         bus->sim->sim_name, DEV_IDLEN);
 2153         }
 2154 
 2155         /*
 2156          * If the user is only interested in busses, there's no
 2157          * reason to descend to the next level in the tree.
 2158          */
 2159         if ((retval & DM_RET_ACTION_MASK) == DM_RET_STOP)
 2160                 return(1);
 2161 
 2162         /*
 2163          * If there is a target generation recorded, check it to
 2164          * make sure the target list hasn't changed.
 2165          */
 2166         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 2167          && (bus == cdm->pos.cookie.bus)
 2168          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 2169          && (cdm->pos.generations[CAM_TARGET_GENERATION] != 0)
 2170          && (cdm->pos.generations[CAM_TARGET_GENERATION] !=
 2171              bus->generation)) {
 2172                 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
 2173                 return(0);
 2174         }
 2175 
 2176         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 2177          && (cdm->pos.cookie.bus == bus)
 2178          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 2179          && (cdm->pos.cookie.target != NULL))
 2180                 return(xpttargettraverse(bus,
 2181                                         (struct cam_et *)cdm->pos.cookie.target,
 2182                                          xptedttargetfunc, arg));
 2183         else
 2184                 return(xpttargettraverse(bus, NULL, xptedttargetfunc, arg));
 2185 }
 2186 
 2187 static int
 2188 xptedttargetfunc(struct cam_et *target, void *arg)
 2189 {
 2190         struct ccb_dev_match *cdm;
 2191 
 2192         cdm = (struct ccb_dev_match *)arg;
 2193 
 2194         /*
 2195          * If there is a device list generation recorded, check it to
 2196          * make sure the device list hasn't changed.
 2197          */
 2198         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 2199          && (cdm->pos.cookie.bus == target->bus)
 2200          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 2201          && (cdm->pos.cookie.target == target)
 2202          && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
 2203          && (cdm->pos.generations[CAM_DEV_GENERATION] != 0)
 2204          && (cdm->pos.generations[CAM_DEV_GENERATION] !=
 2205              target->generation)) {
 2206                 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
 2207                 return(0);
 2208         }
 2209 
 2210         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 2211          && (cdm->pos.cookie.bus == target->bus)
 2212          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 2213          && (cdm->pos.cookie.target == target)
 2214          && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
 2215          && (cdm->pos.cookie.device != NULL))
 2216                 return(xptdevicetraverse(target,
 2217                                         (struct cam_ed *)cdm->pos.cookie.device,
 2218                                          xptedtdevicefunc, arg));
 2219         else
 2220                 return(xptdevicetraverse(target, NULL, xptedtdevicefunc, arg));
 2221 }
 2222 
 2223 static int
 2224 xptedtdevicefunc(struct cam_ed *device, void *arg)
 2225 {
 2226 
 2227         struct ccb_dev_match *cdm;
 2228         dev_match_ret retval;
 2229 
 2230         cdm = (struct ccb_dev_match *)arg;
 2231 
 2232         /*
 2233          * If our position is for something deeper in the tree, that means
 2234          * that we've already seen this node.  So, we keep going down.
 2235          */
 2236         if ((cdm->pos.position_type & CAM_DEV_POS_DEVICE)
 2237          && (cdm->pos.cookie.device == device)
 2238          && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
 2239          && (cdm->pos.cookie.periph != NULL))
 2240                 retval = DM_RET_DESCEND;
 2241         else
 2242                 retval = xptdevicematch(cdm->patterns, cdm->num_patterns,
 2243                                         device);
 2244 
 2245         if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
 2246                 cdm->status = CAM_DEV_MATCH_ERROR;
 2247                 return(0);
 2248         }
 2249 
 2250         /*
 2251          * If the copy flag is set, copy this device out.
 2252          */
 2253         if (retval & DM_RET_COPY) {
 2254                 int spaceleft, j;
 2255 
 2256                 spaceleft = cdm->match_buf_len - (cdm->num_matches *
 2257                         sizeof(struct dev_match_result));
 2258 
 2259                 /*
 2260                  * If we don't have enough space to put in another
 2261                  * match result, save our position and tell the
 2262                  * user there are more devices to check.
 2263                  */
 2264                 if (spaceleft < sizeof(struct dev_match_result)) {
 2265                         bzero(&cdm->pos, sizeof(cdm->pos));
 2266                         cdm->pos.position_type =
 2267                                 CAM_DEV_POS_EDT | CAM_DEV_POS_BUS |
 2268                                 CAM_DEV_POS_TARGET | CAM_DEV_POS_DEVICE;
 2269 
 2270                         cdm->pos.cookie.bus = device->target->bus;
 2271                         cdm->pos.generations[CAM_BUS_GENERATION]=
 2272                                 xsoftc.bus_generation;
 2273                         cdm->pos.cookie.target = device->target;
 2274                         cdm->pos.generations[CAM_TARGET_GENERATION] =
 2275                                 device->target->bus->generation;
 2276                         cdm->pos.cookie.device = device;
 2277                         cdm->pos.generations[CAM_DEV_GENERATION] =
 2278                                 device->target->generation;
 2279                         cdm->status = CAM_DEV_MATCH_MORE;
 2280                         return(0);
 2281                 }
 2282                 j = cdm->num_matches;
 2283                 cdm->num_matches++;
 2284                 cdm->matches[j].type = DEV_MATCH_DEVICE;
 2285                 cdm->matches[j].result.device_result.path_id =
 2286                         device->target->bus->path_id;
 2287                 cdm->matches[j].result.device_result.target_id =
 2288                         device->target->target_id;
 2289                 cdm->matches[j].result.device_result.target_lun =
 2290                         device->lun_id;
 2291                 bcopy(&device->inq_data,
 2292                       &cdm->matches[j].result.device_result.inq_data,
 2293                       sizeof(struct scsi_inquiry_data));
 2294 
 2295                 /* Let the user know whether this device is unconfigured */
 2296                 if (device->flags & CAM_DEV_UNCONFIGURED)
 2297                         cdm->matches[j].result.device_result.flags =
 2298                                 DEV_RESULT_UNCONFIGURED;
 2299                 else
 2300                         cdm->matches[j].result.device_result.flags =
 2301                                 DEV_RESULT_NOFLAG;
 2302         }
 2303 
 2304         /*
 2305          * If the user isn't interested in peripherals, don't descend
 2306          * the tree any further.
 2307          */
 2308         if ((retval & DM_RET_ACTION_MASK) == DM_RET_STOP)
 2309                 return(1);
 2310 
 2311         /*
 2312          * If there is a peripheral list generation recorded, make sure
 2313          * it hasn't changed.
 2314          */
 2315         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 2316          && (device->target->bus == cdm->pos.cookie.bus)
 2317          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 2318          && (device->target == cdm->pos.cookie.target)
 2319          && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
 2320          && (device == cdm->pos.cookie.device)
 2321          && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
 2322          && (cdm->pos.generations[CAM_PERIPH_GENERATION] != 0)
 2323          && (cdm->pos.generations[CAM_PERIPH_GENERATION] !=
 2324              device->generation)){
 2325                 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
 2326                 return(0);
 2327         }
 2328 
 2329         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 2330          && (cdm->pos.cookie.bus == device->target->bus)
 2331          && (cdm->pos.position_type & CAM_DEV_POS_TARGET)
 2332          && (cdm->pos.cookie.target == device->target)
 2333          && (cdm->pos.position_type & CAM_DEV_POS_DEVICE)
 2334          && (cdm->pos.cookie.device == device)
 2335          && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
 2336          && (cdm->pos.cookie.periph != NULL))
 2337                 return(xptperiphtraverse(device,
 2338                                 (struct cam_periph *)cdm->pos.cookie.periph,
 2339                                 xptedtperiphfunc, arg));
 2340         else
 2341                 return(xptperiphtraverse(device, NULL, xptedtperiphfunc, arg));
 2342 }
 2343 
 2344 static int
 2345 xptedtperiphfunc(struct cam_periph *periph, void *arg)
 2346 {
 2347         struct ccb_dev_match *cdm;
 2348         dev_match_ret retval;
 2349 
 2350         cdm = (struct ccb_dev_match *)arg;
 2351 
 2352         retval = xptperiphmatch(cdm->patterns, cdm->num_patterns, periph);
 2353 
 2354         if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
 2355                 cdm->status = CAM_DEV_MATCH_ERROR;
 2356                 return(0);
 2357         }
 2358 
 2359         /*
 2360          * If the copy flag is set, copy this peripheral out.
 2361          */
 2362         if (retval & DM_RET_COPY) {
 2363                 int spaceleft, j;
 2364 
 2365                 spaceleft = cdm->match_buf_len - (cdm->num_matches *
 2366                         sizeof(struct dev_match_result));
 2367 
 2368                 /*
 2369                  * If we don't have enough space to put in another
 2370                  * match result, save our position and tell the
 2371                  * user there are more devices to check.
 2372                  */
 2373                 if (spaceleft < sizeof(struct dev_match_result)) {
 2374                         bzero(&cdm->pos, sizeof(cdm->pos));
 2375                         cdm->pos.position_type =
 2376                                 CAM_DEV_POS_EDT | CAM_DEV_POS_BUS |
 2377                                 CAM_DEV_POS_TARGET | CAM_DEV_POS_DEVICE |
 2378                                 CAM_DEV_POS_PERIPH;
 2379 
 2380                         cdm->pos.cookie.bus = periph->path->bus;
 2381                         cdm->pos.generations[CAM_BUS_GENERATION]=
 2382                                 xsoftc.bus_generation;
 2383                         cdm->pos.cookie.target = periph->path->target;
 2384                         cdm->pos.generations[CAM_TARGET_GENERATION] =
 2385                                 periph->path->bus->generation;
 2386                         cdm->pos.cookie.device = periph->path->device;
 2387                         cdm->pos.generations[CAM_DEV_GENERATION] =
 2388                                 periph->path->target->generation;
 2389                         cdm->pos.cookie.periph = periph;
 2390                         cdm->pos.generations[CAM_PERIPH_GENERATION] =
 2391                                 periph->path->device->generation;
 2392                         cdm->status = CAM_DEV_MATCH_MORE;
 2393                         return(0);
 2394                 }
 2395 
 2396                 j = cdm->num_matches;
 2397                 cdm->num_matches++;
 2398                 cdm->matches[j].type = DEV_MATCH_PERIPH;
 2399                 cdm->matches[j].result.periph_result.path_id =
 2400                         periph->path->bus->path_id;
 2401                 cdm->matches[j].result.periph_result.target_id =
 2402                         periph->path->target->target_id;
 2403                 cdm->matches[j].result.periph_result.target_lun =
 2404                         periph->path->device->lun_id;
 2405                 cdm->matches[j].result.periph_result.unit_number =
 2406                         periph->unit_number;
 2407                 strncpy(cdm->matches[j].result.periph_result.periph_name,
 2408                         periph->periph_name, DEV_IDLEN);
 2409         }
 2410 
 2411         return(1);
 2412 }
 2413 
 2414 static int
 2415 xptedtmatch(struct ccb_dev_match *cdm)
 2416 {
 2417         int ret;
 2418 
 2419         cdm->num_matches = 0;
 2420 
 2421         /*
 2422          * Check the bus list generation.  If it has changed, the user
 2423          * needs to reset everything and start over.
 2424          */
 2425         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 2426          && (cdm->pos.generations[CAM_BUS_GENERATION] != 0)
 2427          && (cdm->pos.generations[CAM_BUS_GENERATION] != xsoftc.bus_generation)) {
 2428                 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
 2429                 return(0);
 2430         }
 2431 
 2432         if ((cdm->pos.position_type & CAM_DEV_POS_BUS)
 2433          && (cdm->pos.cookie.bus != NULL))
 2434                 ret = xptbustraverse((struct cam_eb *)cdm->pos.cookie.bus,
 2435                                      xptedtbusfunc, cdm);
 2436         else
 2437                 ret = xptbustraverse(NULL, xptedtbusfunc, cdm);
 2438 
 2439         /*
 2440          * If we get back 0, that means that we had to stop before fully
 2441          * traversing the EDT.  It also means that one of the subroutines
 2442          * has set the status field to the proper value.  If we get back 1,
 2443          * we've fully traversed the EDT and copied out any matching entries.
 2444          */
 2445         if (ret == 1)
 2446                 cdm->status = CAM_DEV_MATCH_LAST;
 2447 
 2448         return(ret);
 2449 }
 2450 
 2451 static int
 2452 xptplistpdrvfunc(struct periph_driver **pdrv, void *arg)
 2453 {
 2454         struct ccb_dev_match *cdm;
 2455 
 2456         cdm = (struct ccb_dev_match *)arg;
 2457 
 2458         if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
 2459          && (cdm->pos.cookie.pdrv == pdrv)
 2460          && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
 2461          && (cdm->pos.generations[CAM_PERIPH_GENERATION] != 0)
 2462          && (cdm->pos.generations[CAM_PERIPH_GENERATION] !=
 2463              (*pdrv)->generation)) {
 2464                 cdm->status = CAM_DEV_MATCH_LIST_CHANGED;
 2465                 return(0);
 2466         }
 2467 
 2468         if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
 2469          && (cdm->pos.cookie.pdrv == pdrv)
 2470          && (cdm->pos.position_type & CAM_DEV_POS_PERIPH)
 2471          && (cdm->pos.cookie.periph != NULL))
 2472                 return(xptpdperiphtraverse(pdrv,
 2473                                 (struct cam_periph *)cdm->pos.cookie.periph,
 2474                                 xptplistperiphfunc, arg));
 2475         else
 2476                 return(xptpdperiphtraverse(pdrv, NULL,xptplistperiphfunc, arg));
 2477 }
 2478 
 2479 static int
 2480 xptplistperiphfunc(struct cam_periph *periph, void *arg)
 2481 {
 2482         struct ccb_dev_match *cdm;
 2483         dev_match_ret retval;
 2484 
 2485         cdm = (struct ccb_dev_match *)arg;
 2486 
 2487         retval = xptperiphmatch(cdm->patterns, cdm->num_patterns, periph);
 2488 
 2489         if ((retval & DM_RET_ACTION_MASK) == DM_RET_ERROR) {
 2490                 cdm->status = CAM_DEV_MATCH_ERROR;
 2491                 return(0);
 2492         }
 2493 
 2494         /*
 2495          * If the copy flag is set, copy this peripheral out.
 2496          */
 2497         if (retval & DM_RET_COPY) {
 2498                 int spaceleft, j;
 2499 
 2500                 spaceleft = cdm->match_buf_len - (cdm->num_matches *
 2501                         sizeof(struct dev_match_result));
 2502 
 2503                 /*
 2504                  * If we don't have enough space to put in another
 2505                  * match result, save our position and tell the
 2506                  * user there are more devices to check.
 2507                  */
 2508                 if (spaceleft < sizeof(struct dev_match_result)) {
 2509                         struct periph_driver **pdrv;
 2510 
 2511                         pdrv = NULL;
 2512                         bzero(&cdm->pos, sizeof(cdm->pos));
 2513                         cdm->pos.position_type =
 2514                                 CAM_DEV_POS_PDRV | CAM_DEV_POS_PDPTR |
 2515                                 CAM_DEV_POS_PERIPH;
 2516 
 2517                         /*
 2518                          * This may look a bit non-sensical, but it is
 2519                          * actually quite logical.  There are very few
 2520                          * peripheral drivers, and bloating every peripheral
 2521                          * structure with a pointer back to its parent
 2522                          * peripheral driver linker set entry would cost
 2523                          * more in the long run than doing this quick lookup.
 2524                          */
 2525                         for (pdrv = periph_drivers; *pdrv != NULL; pdrv++) {
 2526                                 if (strcmp((*pdrv)->driver_name,
 2527                                     periph->periph_name) == 0)
 2528                                         break;
 2529                         }
 2530 
 2531                         if (*pdrv == NULL) {
 2532                                 cdm->status = CAM_DEV_MATCH_ERROR;
 2533                                 return(0);
 2534                         }
 2535 
 2536                         cdm->pos.cookie.pdrv = pdrv;
 2537                         /*
 2538                          * The periph generation slot does double duty, as
 2539                          * does the periph pointer slot.  They are used for
 2540                          * both edt and pdrv lookups and positioning.
 2541                          */
 2542                         cdm->pos.cookie.periph = periph;
 2543                         cdm->pos.generations[CAM_PERIPH_GENERATION] =
 2544                                 (*pdrv)->generation;
 2545                         cdm->status = CAM_DEV_MATCH_MORE;
 2546                         return(0);
 2547                 }
 2548 
 2549                 j = cdm->num_matches;
 2550                 cdm->num_matches++;
 2551                 cdm->matches[j].type = DEV_MATCH_PERIPH;
 2552                 cdm->matches[j].result.periph_result.path_id =
 2553                         periph->path->bus->path_id;
 2554 
 2555                 /*
 2556                  * The transport layer peripheral doesn't have a target or
 2557                  * lun.
 2558                  */
 2559                 if (periph->path->target)
 2560                         cdm->matches[j].result.periph_result.target_id =
 2561                                 periph->path->target->target_id;
 2562                 else
 2563                         cdm->matches[j].result.periph_result.target_id = -1;
 2564 
 2565                 if (periph->path->device)
 2566                         cdm->matches[j].result.periph_result.target_lun =
 2567                                 periph->path->device->lun_id;
 2568                 else
 2569                         cdm->matches[j].result.periph_result.target_lun = -1;
 2570 
 2571                 cdm->matches[j].result.periph_result.unit_number =
 2572                         periph->unit_number;
 2573                 strncpy(cdm->matches[j].result.periph_result.periph_name,
 2574                         periph->periph_name, DEV_IDLEN);
 2575         }
 2576 
 2577         return(1);
 2578 }
 2579 
 2580 static int
 2581 xptperiphlistmatch(struct ccb_dev_match *cdm)
 2582 {
 2583         int ret;
 2584 
 2585         cdm->num_matches = 0;
 2586 
 2587         /*
 2588          * At this point in the edt traversal function, we check the bus
 2589          * list generation to make sure that no busses have been added or
 2590          * removed since the user last sent a XPT_DEV_MATCH ccb through.
 2591          * For the peripheral driver list traversal function, however, we
 2592          * don't have to worry about new peripheral driver types coming or
 2593          * going; they're in a linker set, and therefore can't change
 2594          * without a recompile.
 2595          */
 2596 
 2597         if ((cdm->pos.position_type & CAM_DEV_POS_PDPTR)
 2598          && (cdm->pos.cookie.pdrv != NULL))
 2599                 ret = xptpdrvtraverse(
 2600                                 (struct periph_driver **)cdm->pos.cookie.pdrv,
 2601                                 xptplistpdrvfunc, cdm);
 2602         else
 2603                 ret = xptpdrvtraverse(NULL, xptplistpdrvfunc, cdm);
 2604 
 2605         /*
 2606          * If we get back 0, that means that we had to stop before fully
 2607          * traversing the peripheral driver tree.  It also means that one of
 2608          * the subroutines has set the status field to the proper value.  If
 2609          * we get back 1, we've fully traversed the EDT and copied out any
 2610          * matching entries.
 2611          */
 2612         if (ret == 1)
 2613                 cdm->status = CAM_DEV_MATCH_LAST;
 2614 
 2615         return(ret);
 2616 }
 2617 
 2618 static int
 2619 xptbustraverse(struct cam_eb *start_bus, xpt_busfunc_t *tr_func, void *arg)
 2620 {
 2621         struct cam_eb *bus, *next_bus;
 2622         int retval;
 2623 
 2624         retval = 1;
 2625 
 2626         mtx_lock(&xsoftc.xpt_topo_lock);
 2627         for (bus = (start_bus ? start_bus : TAILQ_FIRST(&xsoftc.xpt_busses));
 2628              bus != NULL;
 2629              bus = next_bus) {
 2630                 next_bus = TAILQ_NEXT(bus, links);
 2631 
 2632                 mtx_unlock(&xsoftc.xpt_topo_lock);
 2633                 CAM_SIM_LOCK(bus->sim);
 2634                 retval = tr_func(bus, arg);
 2635                 CAM_SIM_UNLOCK(bus->sim);
 2636                 if (retval == 0)
 2637                         return(retval);
 2638                 mtx_lock(&xsoftc.xpt_topo_lock);
 2639         }
 2640         mtx_unlock(&xsoftc.xpt_topo_lock);
 2641 
 2642         return(retval);
 2643 }
 2644 
 2645 int
 2646 xpt_sim_opened(struct cam_sim *sim)
 2647 {
 2648         struct cam_eb *bus;
 2649         struct cam_et *target;
 2650         struct cam_ed *device;
 2651         struct cam_periph *periph;
 2652 
 2653         KASSERT(sim->refcount >= 1, ("sim->refcount >= 1"));
 2654         mtx_assert(sim->mtx, MA_OWNED);
 2655 
 2656         mtx_lock(&xsoftc.xpt_topo_lock);
 2657         TAILQ_FOREACH(bus, &xsoftc.xpt_busses, links) {
 2658                 if (bus->sim != sim)
 2659                         continue;
 2660 
 2661                 TAILQ_FOREACH(target, &bus->et_entries, links) {
 2662                         TAILQ_FOREACH(device, &target->ed_entries, links) {
 2663                                 SLIST_FOREACH(periph, &device->periphs,
 2664                                     periph_links) {
 2665                                         if (periph->refcount > 0) {
 2666                                                 mtx_unlock(&xsoftc.xpt_topo_lock);
 2667                                                 return (1);
 2668                                         }
 2669                                 }
 2670                         }
 2671                 }
 2672         }
 2673 
 2674         mtx_unlock(&xsoftc.xpt_topo_lock);
 2675         return (0);
 2676 }
 2677 
 2678 static int
 2679 xpttargettraverse(struct cam_eb *bus, struct cam_et *start_target,
 2680                   xpt_targetfunc_t *tr_func, void *arg)
 2681 {
 2682         struct cam_et *target, *next_target;
 2683         int retval;
 2684 
 2685         retval = 1;
 2686         for (target = (start_target ? start_target :
 2687                        TAILQ_FIRST(&bus->et_entries));
 2688              target != NULL; target = next_target) {
 2689 
 2690                 next_target = TAILQ_NEXT(target, links);
 2691 
 2692                 retval = tr_func(target, arg);
 2693 
 2694                 if (retval == 0)
 2695                         return(retval);
 2696         }
 2697 
 2698         return(retval);
 2699 }
 2700 
 2701 static int
 2702 xptdevicetraverse(struct cam_et *target, struct cam_ed *start_device,
 2703                   xpt_devicefunc_t *tr_func, void *arg)
 2704 {
 2705         struct cam_ed *device, *next_device;
 2706         int retval;
 2707 
 2708         retval = 1;
 2709         for (device = (start_device ? start_device :
 2710                        TAILQ_FIRST(&target->ed_entries));
 2711              device != NULL;
 2712              device = next_device) {
 2713 
 2714                 next_device = TAILQ_NEXT(device, links);
 2715 
 2716                 retval = tr_func(device, arg);
 2717 
 2718                 if (retval == 0)
 2719                         return(retval);
 2720         }
 2721 
 2722         return(retval);
 2723 }
 2724 
 2725 static int
 2726 xptperiphtraverse(struct cam_ed *device, struct cam_periph *start_periph,
 2727                   xpt_periphfunc_t *tr_func, void *arg)
 2728 {
 2729         struct cam_periph *periph, *next_periph;
 2730         int retval;
 2731 
 2732         retval = 1;
 2733 
 2734         for (periph = (start_periph ? start_periph :
 2735                        SLIST_FIRST(&device->periphs));
 2736              periph != NULL;
 2737              periph = next_periph) {
 2738 
 2739                 next_periph = SLIST_NEXT(periph, periph_links);
 2740 
 2741                 retval = tr_func(periph, arg);
 2742                 if (retval == 0)
 2743                         return(retval);
 2744         }
 2745 
 2746         return(retval);
 2747 }
 2748 
 2749 static int
 2750 xptpdrvtraverse(struct periph_driver **start_pdrv,
 2751                 xpt_pdrvfunc_t *tr_func, void *arg)
 2752 {
 2753         struct periph_driver **pdrv;
 2754         int retval;
 2755 
 2756         retval = 1;
 2757 
 2758         /*
 2759          * We don't traverse the peripheral driver list like we do the
 2760          * other lists, because it is a linker set, and therefore cannot be
 2761          * changed during runtime.  If the peripheral driver list is ever
 2762          * re-done to be something other than a linker set (i.e. it can
 2763          * change while the system is running), the list traversal should
 2764          * be modified to work like the other traversal functions.
 2765          */
 2766         for (pdrv = (start_pdrv ? start_pdrv : periph_drivers);
 2767              *pdrv != NULL; pdrv++) {
 2768                 retval = tr_func(pdrv, arg);
 2769 
 2770                 if (retval == 0)
 2771                         return(retval);
 2772         }
 2773 
 2774         return(retval);
 2775 }
 2776 
 2777 static int
 2778 xptpdperiphtraverse(struct periph_driver **pdrv,
 2779                     struct cam_periph *start_periph,
 2780                     xpt_periphfunc_t *tr_func, void *arg)
 2781 {
 2782         struct cam_periph *periph, *next_periph;
 2783         int retval;
 2784 
 2785         retval = 1;
 2786 
 2787         for (periph = (start_periph ? start_periph :
 2788              TAILQ_FIRST(&(*pdrv)->units)); periph != NULL;
 2789              periph = next_periph) {
 2790 
 2791                 next_periph = TAILQ_NEXT(periph, unit_links);
 2792 
 2793                 retval = tr_func(periph, arg);
 2794                 if (retval == 0)
 2795                         return(retval);
 2796         }
 2797         return(retval);
 2798 }
 2799 
 2800 static int
 2801 xptdefbusfunc(struct cam_eb *bus, void *arg)
 2802 {
 2803         struct xpt_traverse_config *tr_config;
 2804 
 2805         tr_config = (struct xpt_traverse_config *)arg;
 2806 
 2807         if (tr_config->depth == XPT_DEPTH_BUS) {
 2808                 xpt_busfunc_t *tr_func;
 2809 
 2810                 tr_func = (xpt_busfunc_t *)tr_config->tr_func;
 2811 
 2812                 return(tr_func(bus, tr_config->tr_arg));
 2813         } else
 2814                 return(xpttargettraverse(bus, NULL, xptdeftargetfunc, arg));
 2815 }
 2816 
 2817 static int
 2818 xptdeftargetfunc(struct cam_et *target, void *arg)
 2819 {
 2820         struct xpt_traverse_config *tr_config;
 2821 
 2822         tr_config = (struct xpt_traverse_config *)arg;
 2823 
 2824         if (tr_config->depth == XPT_DEPTH_TARGET) {
 2825                 xpt_targetfunc_t *tr_func;
 2826 
 2827                 tr_func = (xpt_targetfunc_t *)tr_config->tr_func;
 2828 
 2829                 return(tr_func(target, tr_config->tr_arg));
 2830         } else
 2831                 return(xptdevicetraverse(target, NULL, xptdefdevicefunc, arg));
 2832 }
 2833 
 2834 static int
 2835 xptdefdevicefunc(struct cam_ed *device, void *arg)
 2836 {
 2837         struct xpt_traverse_config *tr_config;
 2838 
 2839         tr_config = (struct xpt_traverse_config *)arg;
 2840 
 2841         if (tr_config->depth == XPT_DEPTH_DEVICE) {
 2842                 xpt_devicefunc_t *tr_func;
 2843 
 2844                 tr_func = (xpt_devicefunc_t *)tr_config->tr_func;
 2845 
 2846                 return(tr_func(device, tr_config->tr_arg));
 2847         } else
 2848                 return(xptperiphtraverse(device, NULL, xptdefperiphfunc, arg));
 2849 }
 2850 
 2851 static int
 2852 xptdefperiphfunc(struct cam_periph *periph, void *arg)
 2853 {
 2854         struct xpt_traverse_config *tr_config;
 2855         xpt_periphfunc_t *tr_func;
 2856 
 2857         tr_config = (struct xpt_traverse_config *)arg;
 2858 
 2859         tr_func = (xpt_periphfunc_t *)tr_config->tr_func;
 2860 
 2861         /*
 2862          * Unlike the other default functions, we don't check for depth
 2863          * here.  The peripheral driver level is the last level in the EDT,
 2864          * so if we're here, we should execute the function in question.
 2865          */
 2866         return(tr_func(periph, tr_config->tr_arg));
 2867 }
 2868 
 2869 /*
 2870  * Execute the given function for every bus in the EDT.
 2871  */
 2872 static int
 2873 xpt_for_all_busses(xpt_busfunc_t *tr_func, void *arg)
 2874 {
 2875         struct xpt_traverse_config tr_config;
 2876 
 2877         tr_config.depth = XPT_DEPTH_BUS;
 2878         tr_config.tr_func = tr_func;
 2879         tr_config.tr_arg = arg;
 2880 
 2881         return(xptbustraverse(NULL, xptdefbusfunc, &tr_config));
 2882 }
 2883 
 2884 /*
 2885  * Execute the given function for every device in the EDT.
 2886  */
 2887 static int
 2888 xpt_for_all_devices(xpt_devicefunc_t *tr_func, void *arg)
 2889 {
 2890         struct xpt_traverse_config tr_config;
 2891 
 2892         tr_config.depth = XPT_DEPTH_DEVICE;
 2893         tr_config.tr_func = tr_func;
 2894         tr_config.tr_arg = arg;
 2895 
 2896         return(xptbustraverse(NULL, xptdefbusfunc, &tr_config));
 2897 }
 2898 
 2899 static int
 2900 xptsetasyncfunc(struct cam_ed *device, void *arg)
 2901 {
 2902         struct cam_path path;
 2903         struct ccb_getdev cgd;
 2904         struct async_node *cur_entry;
 2905 
 2906         cur_entry = (struct async_node *)arg;
 2907 
 2908         /*
 2909          * Don't report unconfigured devices (Wildcard devs,
 2910          * devices only for target mode, device instances
 2911          * that have been invalidated but are waiting for
 2912          * their last reference count to be released).
 2913          */
 2914         if ((device->flags & CAM_DEV_UNCONFIGURED) != 0)
 2915                 return (1);
 2916 
 2917         xpt_compile_path(&path,
 2918                          NULL,
 2919                          device->target->bus->path_id,
 2920                          device->target->target_id,
 2921                          device->lun_id);
 2922         xpt_setup_ccb(&cgd.ccb_h, &path, /*priority*/1);
 2923         cgd.ccb_h.func_code = XPT_GDEV_TYPE;
 2924         xpt_action((union ccb *)&cgd);
 2925         cur_entry->callback(cur_entry->callback_arg,
 2926                             AC_FOUND_DEVICE,
 2927                             &path, &cgd);
 2928         xpt_release_path(&path);
 2929 
 2930         return(1);
 2931 }
 2932 
 2933 static int
 2934 xptsetasyncbusfunc(struct cam_eb *bus, void *arg)
 2935 {
 2936         struct cam_path path;
 2937         struct ccb_pathinq cpi;
 2938         struct async_node *cur_entry;
 2939 
 2940         cur_entry = (struct async_node *)arg;
 2941 
 2942         xpt_compile_path(&path, /*periph*/NULL,
 2943                          bus->sim->path_id,
 2944                          CAM_TARGET_WILDCARD,
 2945                          CAM_LUN_WILDCARD);
 2946         xpt_setup_ccb(&cpi.ccb_h, &path, /*priority*/1);
 2947         cpi.ccb_h.func_code = XPT_PATH_INQ;
 2948         xpt_action((union ccb *)&cpi);
 2949         cur_entry->callback(cur_entry->callback_arg,
 2950                             AC_PATH_REGISTERED,
 2951                             &path, &cpi);
 2952         xpt_release_path(&path);
 2953 
 2954         return(1);
 2955 }
 2956 
 2957 static void
 2958 xpt_action_sasync_cb(void *context, int pending)
 2959 {
 2960         struct async_node *cur_entry;
 2961         struct xpt_task *task;
 2962         uint32_t added;
 2963 
 2964         task = (struct xpt_task *)context;
 2965         cur_entry = (struct async_node *)task->data1;
 2966         added = task->data2;
 2967 
 2968         if ((added & AC_FOUND_DEVICE) != 0) {
 2969                 /*
 2970                  * Get this peripheral up to date with all
 2971                  * the currently existing devices.
 2972                  */
 2973                 xpt_for_all_devices(xptsetasyncfunc, cur_entry);
 2974         }
 2975         if ((added & AC_PATH_REGISTERED) != 0) {
 2976                 /*
 2977                  * Get this peripheral up to date with all
 2978                  * the currently existing busses.
 2979                  */
 2980                 xpt_for_all_busses(xptsetasyncbusfunc, cur_entry);
 2981         }
 2982 
 2983         free(task, M_CAMXPT);
 2984 }
 2985 
 2986 void
 2987 xpt_action(union ccb *start_ccb)
 2988 {
 2989 
 2990         CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_action\n"));
 2991 
 2992         start_ccb->ccb_h.status = CAM_REQ_INPROG;
 2993 
 2994         switch (start_ccb->ccb_h.func_code) {
 2995         case XPT_SCSI_IO:
 2996         {
 2997                 struct cam_ed *device;
 2998 #ifdef CAMDEBUG
 2999                 char cdb_str[(SCSI_MAX_CDBLEN * 3) + 1];
 3000                 struct cam_path *path;
 3001 
 3002                 path = start_ccb->ccb_h.path;
 3003 #endif
 3004 
 3005                 /*
 3006                  * For the sake of compatibility with SCSI-1
 3007                  * devices that may not understand the identify
 3008                  * message, we include lun information in the
 3009                  * second byte of all commands.  SCSI-1 specifies
 3010                  * that luns are a 3 bit value and reserves only 3
 3011                  * bits for lun information in the CDB.  Later
 3012                  * revisions of the SCSI spec allow for more than 8
 3013                  * luns, but have deprecated lun information in the
 3014                  * CDB.  So, if the lun won't fit, we must omit.
 3015                  *
 3016                  * Also be aware that during initial probing for devices,
 3017                  * the inquiry information is unknown but initialized to 0.
 3018                  * This means that this code will be exercised while probing
 3019                  * devices with an ANSI revision greater than 2.
 3020                  */
 3021                 device = start_ccb->ccb_h.path->device;
 3022                 if (device->protocol_version <= SCSI_REV_2
 3023                  && start_ccb->ccb_h.target_lun < 8
 3024                  && (start_ccb->ccb_h.flags & CAM_CDB_POINTER) == 0) {
 3025 
 3026                         start_ccb->csio.cdb_io.cdb_bytes[1] |=
 3027                             start_ccb->ccb_h.target_lun << 5;
 3028                 }
 3029                 start_ccb->csio.scsi_status = SCSI_STATUS_OK;
 3030                 CAM_DEBUG(path, CAM_DEBUG_CDB,("%s. CDB: %s\n",
 3031                           scsi_op_desc(start_ccb->csio.cdb_io.cdb_bytes[0],
 3032                                        &path->device->inq_data),
 3033                           scsi_cdb_string(start_ccb->csio.cdb_io.cdb_bytes,
 3034                                           cdb_str, sizeof(cdb_str))));
 3035         }
 3036         /* FALLTHROUGH */
 3037         case XPT_TARGET_IO:
 3038         case XPT_CONT_TARGET_IO:
 3039                 start_ccb->csio.sense_resid = 0;
 3040                 start_ccb->csio.resid = 0;
 3041                 /* FALLTHROUGH */
 3042         case XPT_RESET_DEV:
 3043         case XPT_ENG_EXEC:
 3044         {
 3045                 struct cam_path *path;
 3046                 int runq;
 3047 
 3048                 path = start_ccb->ccb_h.path;
 3049 
 3050                 cam_ccbq_insert_ccb(&path->device->ccbq, start_ccb);
 3051                 if (path->device->qfrozen_cnt == 0)
 3052                         runq = xpt_schedule_dev_sendq(path->bus, path->device);
 3053                 else
 3054                         runq = 0;
 3055                 if (runq != 0)
 3056                         xpt_run_dev_sendq(path->bus);
 3057                 break;
 3058         }
 3059         case XPT_SET_TRAN_SETTINGS:
 3060         {
 3061                 xpt_set_transfer_settings(&start_ccb->cts,
 3062                                           start_ccb->ccb_h.path->device,
 3063                                           /*async_update*/FALSE);
 3064                 break;
 3065         }
 3066         case XPT_CALC_GEOMETRY:
 3067         {
 3068                 struct cam_sim *sim;
 3069 
 3070                 /* Filter out garbage */
 3071                 if (start_ccb->ccg.block_size == 0
 3072                  || start_ccb->ccg.volume_size == 0) {
 3073                         start_ccb->ccg.cylinders = 0;
 3074                         start_ccb->ccg.heads = 0;
 3075                         start_ccb->ccg.secs_per_track = 0;
 3076                         start_ccb->ccb_h.status = CAM_REQ_CMP;
 3077                         break;
 3078                 }
 3079 #ifdef PC98
 3080                 /*
 3081                  * In a PC-98 system, geometry translation depens on
 3082                  * the "real" device geometry obtained from mode page 4.
 3083                  * SCSI geometry translation is performed in the
 3084                  * initialization routine of the SCSI BIOS and the result
 3085                  * stored in host memory.  If the translation is available
 3086                  * in host memory, use it.  If not, rely on the default
 3087                  * translation the device driver performs.
 3088                  */
 3089                 if (scsi_da_bios_params(&start_ccb->ccg) != 0) {
 3090                         start_ccb->ccb_h.status = CAM_REQ_CMP;
 3091                         break;
 3092                 }
 3093 #endif
 3094                 sim = start_ccb->ccb_h.path->bus->sim;
 3095                 (*(sim->sim_action))(sim, start_ccb);
 3096                 break;
 3097         }
 3098         case XPT_ABORT:
 3099         {
 3100                 union ccb* abort_ccb;
 3101 
 3102                 abort_ccb = start_ccb->cab.abort_ccb;
 3103                 if (XPT_FC_IS_DEV_QUEUED(abort_ccb)) {
 3104 
 3105                         if (abort_ccb->ccb_h.pinfo.index >= 0) {
 3106                                 struct cam_ccbq *ccbq;
 3107 
 3108                                 ccbq = &abort_ccb->ccb_h.path->device->ccbq;
 3109                                 cam_ccbq_remove_ccb(ccbq, abort_ccb);
 3110                                 abort_ccb->ccb_h.status =
 3111                                     CAM_REQ_ABORTED|CAM_DEV_QFRZN;
 3112                                 xpt_freeze_devq(abort_ccb->ccb_h.path, 1);
 3113                                 xpt_done(abort_ccb);
 3114                                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 3115                                 break;
 3116                         }
 3117                         if (abort_ccb->ccb_h.pinfo.index == CAM_UNQUEUED_INDEX
 3118                          && (abort_ccb->ccb_h.status & CAM_SIM_QUEUED) == 0) {
 3119                                 /*
 3120                                  * We've caught this ccb en route to
 3121                                  * the SIM.  Flag it for abort and the
 3122                                  * SIM will do so just before starting
 3123                                  * real work on the CCB.
 3124                                  */
 3125                                 abort_ccb->ccb_h.status =
 3126                                     CAM_REQ_ABORTED|CAM_DEV_QFRZN;
 3127                                 xpt_freeze_devq(abort_ccb->ccb_h.path, 1);
 3128                                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 3129                                 break;
 3130                         }
 3131                 }
 3132                 if (XPT_FC_IS_QUEUED(abort_ccb)
 3133                  && (abort_ccb->ccb_h.pinfo.index == CAM_DONEQ_INDEX)) {
 3134                         /*
 3135                          * It's already completed but waiting
 3136                          * for our SWI to get to it.
 3137                          */
 3138                         start_ccb->ccb_h.status = CAM_UA_ABORT;
 3139                         break;
 3140                 }
 3141                 /*
 3142                  * If we weren't able to take care of the abort request
 3143                  * in the XPT, pass the request down to the SIM for processing.
 3144                  */
 3145         }
 3146         /* FALLTHROUGH */
 3147         case XPT_ACCEPT_TARGET_IO:
 3148         case XPT_EN_LUN:
 3149         case XPT_IMMED_NOTIFY:
 3150         case XPT_NOTIFY_ACK:
 3151         case XPT_GET_TRAN_SETTINGS:
 3152         case XPT_RESET_BUS:
 3153         {
 3154                 struct cam_sim *sim;
 3155 
 3156                 sim = start_ccb->ccb_h.path->bus->sim;
 3157                 (*(sim->sim_action))(sim, start_ccb);
 3158                 break;
 3159         }
 3160         case XPT_PATH_INQ:
 3161         {
 3162                 struct cam_sim *sim;
 3163 
 3164                 sim = start_ccb->ccb_h.path->bus->sim;
 3165                 (*(sim->sim_action))(sim, start_ccb);
 3166                 break;
 3167         }
 3168         case XPT_PATH_STATS:
 3169                 start_ccb->cpis.last_reset =
 3170                         start_ccb->ccb_h.path->bus->last_reset;
 3171                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 3172                 break;
 3173         case XPT_GDEV_TYPE:
 3174         {
 3175                 struct cam_ed *dev;
 3176 
 3177                 dev = start_ccb->ccb_h.path->device;
 3178                 if ((dev->flags & CAM_DEV_UNCONFIGURED) != 0) {
 3179                         start_ccb->ccb_h.status = CAM_DEV_NOT_THERE;
 3180                 } else {
 3181                         struct ccb_getdev *cgd;
 3182                         struct cam_eb *bus;
 3183                         struct cam_et *tar;
 3184 
 3185                         cgd = &start_ccb->cgd;
 3186                         bus = cgd->ccb_h.path->bus;
 3187                         tar = cgd->ccb_h.path->target;
 3188                         cgd->inq_data = dev->inq_data;
 3189                         cgd->ccb_h.status = CAM_REQ_CMP;
 3190                         cgd->serial_num_len = dev->serial_num_len;
 3191                         if ((dev->serial_num_len > 0)
 3192                          && (dev->serial_num != NULL))
 3193                                 bcopy(dev->serial_num, cgd->serial_num,
 3194                                       dev->serial_num_len);
 3195                 }
 3196                 break;
 3197         }
 3198         case XPT_GDEV_STATS:
 3199         {
 3200                 struct cam_ed *dev;
 3201 
 3202                 dev = start_ccb->ccb_h.path->device;
 3203                 if ((dev->flags & CAM_DEV_UNCONFIGURED) != 0) {
 3204                         start_ccb->ccb_h.status = CAM_DEV_NOT_THERE;
 3205                 } else {
 3206                         struct ccb_getdevstats *cgds;
 3207                         struct cam_eb *bus;
 3208                         struct cam_et *tar;
 3209 
 3210                         cgds = &start_ccb->cgds;
 3211                         bus = cgds->ccb_h.path->bus;
 3212                         tar = cgds->ccb_h.path->target;
 3213                         cgds->dev_openings = dev->ccbq.dev_openings;
 3214                         cgds->dev_active = dev->ccbq.dev_active;
 3215                         cgds->devq_openings = dev->ccbq.devq_openings;
 3216                         cgds->devq_queued = dev->ccbq.queue.entries;
 3217                         cgds->held = dev->ccbq.held;
 3218                         cgds->last_reset = tar->last_reset;
 3219                         cgds->maxtags = dev->quirk->maxtags;
 3220                         cgds->mintags = dev->quirk->mintags;
 3221                         if (timevalcmp(&tar->last_reset, &bus->last_reset, <))
 3222                                 cgds->last_reset = bus->last_reset;
 3223                         cgds->ccb_h.status = CAM_REQ_CMP;
 3224                 }
 3225                 break;
 3226         }
 3227         case XPT_GDEVLIST:
 3228         {
 3229                 struct cam_periph       *nperiph;
 3230                 struct periph_list      *periph_head;
 3231                 struct ccb_getdevlist   *cgdl;
 3232                 u_int                   i;
 3233                 struct cam_ed           *device;
 3234                 int                     found;
 3235 
 3236 
 3237                 found = 0;
 3238 
 3239                 /*
 3240                  * Don't want anyone mucking with our data.
 3241                  */
 3242                 device = start_ccb->ccb_h.path->device;
 3243                 periph_head = &device->periphs;
 3244                 cgdl = &start_ccb->cgdl;
 3245 
 3246                 /*
 3247                  * Check and see if the list has changed since the user
 3248                  * last requested a list member.  If so, tell them that the
 3249                  * list has changed, and therefore they need to start over
 3250                  * from the beginning.
 3251                  */
 3252                 if ((cgdl->index != 0) &&
 3253                     (cgdl->generation != device->generation)) {
 3254                         cgdl->status = CAM_GDEVLIST_LIST_CHANGED;
 3255                         break;
 3256                 }
 3257 
 3258                 /*
 3259                  * Traverse the list of peripherals and attempt to find
 3260                  * the requested peripheral.
 3261                  */
 3262                 for (nperiph = SLIST_FIRST(periph_head), i = 0;
 3263                      (nperiph != NULL) && (i <= cgdl->index);
 3264                      nperiph = SLIST_NEXT(nperiph, periph_links), i++) {
 3265                         if (i == cgdl->index) {
 3266                                 strncpy(cgdl->periph_name,
 3267                                         nperiph->periph_name,
 3268                                         DEV_IDLEN);
 3269                                 cgdl->unit_number = nperiph->unit_number;
 3270                                 found = 1;
 3271                         }
 3272                 }
 3273                 if (found == 0) {
 3274                         cgdl->status = CAM_GDEVLIST_ERROR;
 3275                         break;
 3276                 }
 3277 
 3278                 if (nperiph == NULL)
 3279                         cgdl->status = CAM_GDEVLIST_LAST_DEVICE;
 3280                 else
 3281                         cgdl->status = CAM_GDEVLIST_MORE_DEVS;
 3282 
 3283                 cgdl->index++;
 3284                 cgdl->generation = device->generation;
 3285 
 3286                 cgdl->ccb_h.status = CAM_REQ_CMP;
 3287                 break;
 3288         }
 3289         case XPT_DEV_MATCH:
 3290         {
 3291                 dev_pos_type position_type;
 3292                 struct ccb_dev_match *cdm;
 3293 
 3294                 cdm = &start_ccb->cdm;
 3295 
 3296                 /*
 3297                  * There are two ways of getting at information in the EDT.
 3298                  * The first way is via the primary EDT tree.  It starts
 3299                  * with a list of busses, then a list of targets on a bus,
 3300                  * then devices/luns on a target, and then peripherals on a
 3301                  * device/lun.  The "other" way is by the peripheral driver
 3302                  * lists.  The peripheral driver lists are organized by
 3303                  * peripheral driver.  (obviously)  So it makes sense to
 3304                  * use the peripheral driver list if the user is looking
 3305                  * for something like "da1", or all "da" devices.  If the
 3306                  * user is looking for something on a particular bus/target
 3307                  * or lun, it's generally better to go through the EDT tree.
 3308                  */
 3309 
 3310                 if (cdm->pos.position_type != CAM_DEV_POS_NONE)
 3311                         position_type = cdm->pos.position_type;
 3312                 else {
 3313                         u_int i;
 3314 
 3315                         position_type = CAM_DEV_POS_NONE;
 3316 
 3317                         for (i = 0; i < cdm->num_patterns; i++) {
 3318                                 if ((cdm->patterns[i].type == DEV_MATCH_BUS)
 3319                                  ||(cdm->patterns[i].type == DEV_MATCH_DEVICE)){
 3320                                         position_type = CAM_DEV_POS_EDT;
 3321                                         break;
 3322                                 }
 3323                         }
 3324 
 3325                         if (cdm->num_patterns == 0)
 3326                                 position_type = CAM_DEV_POS_EDT;
 3327                         else if (position_type == CAM_DEV_POS_NONE)
 3328                                 position_type = CAM_DEV_POS_PDRV;
 3329                 }
 3330 
 3331                 switch(position_type & CAM_DEV_POS_TYPEMASK) {
 3332                 case CAM_DEV_POS_EDT:
 3333                         xptedtmatch(cdm);
 3334                         break;
 3335                 case CAM_DEV_POS_PDRV:
 3336                         xptperiphlistmatch(cdm);
 3337                         break;
 3338                 default:
 3339                         cdm->status = CAM_DEV_MATCH_ERROR;
 3340                         break;
 3341                 }
 3342 
 3343                 if (cdm->status == CAM_DEV_MATCH_ERROR)
 3344                         start_ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 3345                 else
 3346                         start_ccb->ccb_h.status = CAM_REQ_CMP;
 3347 
 3348                 break;
 3349         }
 3350         case XPT_SASYNC_CB:
 3351         {
 3352                 struct ccb_setasync *csa;
 3353                 struct async_node *cur_entry;
 3354                 struct async_list *async_head;
 3355                 u_int32_t added;
 3356 
 3357                 csa = &start_ccb->csa;
 3358                 added = csa->event_enable;
 3359                 async_head = &csa->ccb_h.path->device->asyncs;
 3360 
 3361                 /*
 3362                  * If there is already an entry for us, simply
 3363                  * update it.
 3364                  */
 3365                 cur_entry = SLIST_FIRST(async_head);
 3366                 while (cur_entry != NULL) {
 3367                         if ((cur_entry->callback_arg == csa->callback_arg)
 3368                          && (cur_entry->callback == csa->callback))
 3369                                 break;
 3370                         cur_entry = SLIST_NEXT(cur_entry, links);
 3371                 }
 3372 
 3373                 if (cur_entry != NULL) {
 3374                         /*
 3375                          * If the request has no flags set,
 3376                          * remove the entry.
 3377                          */
 3378                         added &= ~cur_entry->event_enable;
 3379                         if (csa->event_enable == 0) {
 3380                                 SLIST_REMOVE(async_head, cur_entry,
 3381                                              async_node, links);
 3382                                 csa->ccb_h.path->device->refcount--;
 3383                                 free(cur_entry, M_CAMXPT);
 3384                         } else {
 3385                                 cur_entry->event_enable = csa->event_enable;
 3386                         }
 3387                 } else {
 3388                         cur_entry = malloc(sizeof(*cur_entry), M_CAMXPT,
 3389                                            M_NOWAIT);
 3390                         if (cur_entry == NULL) {
 3391                                 csa->ccb_h.status = CAM_RESRC_UNAVAIL;
 3392                                 break;
 3393                         }
 3394                         cur_entry->event_enable = csa->event_enable;
 3395                         cur_entry->callback_arg = csa->callback_arg;
 3396                         cur_entry->callback = csa->callback;
 3397                         SLIST_INSERT_HEAD(async_head, cur_entry, links);
 3398                         csa->ccb_h.path->device->refcount++;
 3399                 }
 3400 
 3401                 /*
 3402                  * Need to decouple this operation via a taqskqueue so that
 3403                  * the locking doesn't become a mess.
 3404                  */
 3405                 if ((added & (AC_FOUND_DEVICE | AC_PATH_REGISTERED)) != 0) {
 3406                         struct xpt_task *task;
 3407 
 3408                         task = malloc(sizeof(struct xpt_task), M_CAMXPT,
 3409                                       M_NOWAIT);
 3410                         if (task == NULL) {
 3411                                 csa->ccb_h.status = CAM_RESRC_UNAVAIL;
 3412                                 break;
 3413                         }
 3414 
 3415                         TASK_INIT(&task->task, 0, xpt_action_sasync_cb, task);
 3416                         task->data1 = cur_entry;
 3417                         task->data2 = added;
 3418                         taskqueue_enqueue(taskqueue_thread, &task->task);
 3419                 }
 3420 
 3421                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 3422                 break;
 3423         }
 3424         case XPT_REL_SIMQ:
 3425         {
 3426                 struct ccb_relsim *crs;
 3427                 struct cam_ed *dev;
 3428 
 3429                 crs = &start_ccb->crs;
 3430                 dev = crs->ccb_h.path->device;
 3431                 if (dev == NULL) {
 3432 
 3433                         crs->ccb_h.status = CAM_DEV_NOT_THERE;
 3434                         break;
 3435                 }
 3436 
 3437                 if ((crs->release_flags & RELSIM_ADJUST_OPENINGS) != 0) {
 3438 
 3439                         if (INQ_DATA_TQ_ENABLED(&dev->inq_data)) {
 3440                                 /* Don't ever go below one opening */
 3441                                 if (crs->openings > 0) {
 3442                                         xpt_dev_ccbq_resize(crs->ccb_h.path,
 3443                                                             crs->openings);
 3444 
 3445                                         if (bootverbose) {
 3446                                                 xpt_print(crs->ccb_h.path,
 3447                                                     "tagged openings now %d\n",
 3448                                                     crs->openings);
 3449                                         }
 3450                                 }
 3451                         }
 3452                 }
 3453 
 3454                 if ((crs->release_flags & RELSIM_RELEASE_AFTER_TIMEOUT) != 0) {
 3455 
 3456                         if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) {
 3457 
 3458                                 /*
 3459                                  * Just extend the old timeout and decrement
 3460                                  * the freeze count so that a single timeout
 3461                                  * is sufficient for releasing the queue.
 3462                                  */
 3463                                 start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE;
 3464                                 callout_stop(&dev->callout);
 3465                         } else {
 3466 
 3467                                 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
 3468                         }
 3469 
 3470                         callout_reset(&dev->callout,
 3471                             (crs->release_timeout * hz) / 1000,
 3472                             xpt_release_devq_timeout, dev);
 3473 
 3474                         dev->flags |= CAM_DEV_REL_TIMEOUT_PENDING;
 3475 
 3476                 }
 3477 
 3478                 if ((crs->release_flags & RELSIM_RELEASE_AFTER_CMDCMPLT) != 0) {
 3479 
 3480                         if ((dev->flags & CAM_DEV_REL_ON_COMPLETE) != 0) {
 3481                                 /*
 3482                                  * Decrement the freeze count so that a single
 3483                                  * completion is still sufficient to unfreeze
 3484                                  * the queue.
 3485                                  */
 3486                                 start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE;
 3487                         } else {
 3488 
 3489                                 dev->flags |= CAM_DEV_REL_ON_COMPLETE;
 3490                                 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
 3491                         }
 3492                 }
 3493 
 3494                 if ((crs->release_flags & RELSIM_RELEASE_AFTER_QEMPTY) != 0) {
 3495 
 3496                         if ((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0
 3497                          || (dev->ccbq.dev_active == 0)) {
 3498 
 3499                                 start_ccb->ccb_h.flags &= ~CAM_DEV_QFREEZE;
 3500                         } else {
 3501 
 3502                                 dev->flags |= CAM_DEV_REL_ON_QUEUE_EMPTY;
 3503                                 start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
 3504                         }
 3505                 }
 3506 
 3507                 if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) == 0) {
 3508 
 3509                         xpt_release_devq(crs->ccb_h.path, /*count*/1,
 3510                                          /*run_queue*/TRUE);
 3511                 }
 3512                 start_ccb->crs.qfrozen_cnt = dev->qfrozen_cnt;
 3513                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 3514                 break;
 3515         }
 3516         case XPT_SCAN_BUS:
 3517                 xpt_scan_bus(start_ccb->ccb_h.path->periph, start_ccb);
 3518                 break;
 3519         case XPT_SCAN_LUN:
 3520                 xpt_scan_lun(start_ccb->ccb_h.path->periph,
 3521                              start_ccb->ccb_h.path, start_ccb->crcn.flags,
 3522                              start_ccb);
 3523                 break;
 3524         case XPT_DEBUG: {
 3525 #ifdef CAMDEBUG
 3526 #ifdef CAM_DEBUG_DELAY
 3527                 cam_debug_delay = CAM_DEBUG_DELAY;
 3528 #endif
 3529                 cam_dflags = start_ccb->cdbg.flags;
 3530                 if (cam_dpath != NULL) {
 3531                         xpt_free_path(cam_dpath);
 3532                         cam_dpath = NULL;
 3533                 }
 3534 
 3535                 if (cam_dflags != CAM_DEBUG_NONE) {
 3536                         if (xpt_create_path(&cam_dpath, xpt_periph,
 3537                                             start_ccb->ccb_h.path_id,
 3538                                             start_ccb->ccb_h.target_id,
 3539                                             start_ccb->ccb_h.target_lun) !=
 3540                                             CAM_REQ_CMP) {
 3541                                 start_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 3542                                 cam_dflags = CAM_DEBUG_NONE;
 3543                         } else {
 3544                                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 3545                                 xpt_print(cam_dpath, "debugging flags now %x\n",
 3546                                     cam_dflags);
 3547                         }
 3548                 } else {
 3549                         cam_dpath = NULL;
 3550                         start_ccb->ccb_h.status = CAM_REQ_CMP;
 3551                 }
 3552 #else /* !CAMDEBUG */
 3553                 start_ccb->ccb_h.status = CAM_FUNC_NOTAVAIL;
 3554 #endif /* CAMDEBUG */
 3555                 break;
 3556         }
 3557         case XPT_NOOP:
 3558                 if ((start_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0)
 3559                         xpt_freeze_devq(start_ccb->ccb_h.path, 1);
 3560                 start_ccb->ccb_h.status = CAM_REQ_CMP;
 3561                 break;
 3562         default:
 3563         case XPT_SDEV_TYPE:
 3564         case XPT_TERM_IO:
 3565         case XPT_ENG_INQ:
 3566                 /* XXX Implement */
 3567                 start_ccb->ccb_h.status = CAM_PROVIDE_FAIL;
 3568                 break;
 3569         }
 3570 }
 3571 
 3572 void
 3573 xpt_polled_action(union ccb *start_ccb)
 3574 {
 3575         u_int32_t timeout;
 3576         struct    cam_sim *sim;
 3577         struct    cam_devq *devq;
 3578         struct    cam_ed *dev;
 3579 
 3580 
 3581         timeout = start_ccb->ccb_h.timeout;
 3582         sim = start_ccb->ccb_h.path->bus->sim;
 3583         devq = sim->devq;
 3584         dev = start_ccb->ccb_h.path->device;
 3585 
 3586         mtx_assert(sim->mtx, MA_OWNED);
 3587 
 3588         /*
 3589          * Steal an opening so that no other queued requests
 3590          * can get it before us while we simulate interrupts.
 3591          */
 3592         dev->ccbq.devq_openings--;
 3593         dev->ccbq.dev_openings--;
 3594 
 3595         while(((devq != NULL && devq->send_openings <= 0) ||
 3596            dev->ccbq.dev_openings < 0) && (--timeout > 0)) {
 3597                 DELAY(1000);
 3598                 (*(sim->sim_poll))(sim);
 3599                 camisr_runqueue(&sim->sim_doneq);
 3600         }
 3601 
 3602         dev->ccbq.devq_openings++;
 3603         dev->ccbq.dev_openings++;
 3604 
 3605         if (timeout != 0) {
 3606                 xpt_action(start_ccb);
 3607                 while(--timeout > 0) {
 3608                         (*(sim->sim_poll))(sim);
 3609                         camisr_runqueue(&sim->sim_doneq);
 3610                         if ((start_ccb->ccb_h.status  & CAM_STATUS_MASK)
 3611                             != CAM_REQ_INPROG)
 3612                                 break;
 3613                         DELAY(1000);
 3614                 }
 3615                 if (timeout == 0) {
 3616                         /*
 3617                          * XXX Is it worth adding a sim_timeout entry
 3618                          * point so we can attempt recovery?  If
 3619                          * this is only used for dumps, I don't think
 3620                          * it is.
 3621                          */
 3622                         start_ccb->ccb_h.status = CAM_CMD_TIMEOUT;
 3623                 }
 3624         } else {
 3625                 start_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 3626         }
 3627 }
 3628 
 3629 /*
 3630  * Schedule a peripheral driver to receive a ccb when it's
 3631  * target device has space for more transactions.
 3632  */
 3633 void
 3634 xpt_schedule(struct cam_periph *perph, u_int32_t new_priority)
 3635 {
 3636         struct cam_ed *device;
 3637         int runq;
 3638 
 3639         mtx_assert(perph->sim->mtx, MA_OWNED);
 3640 
 3641         CAM_DEBUG(perph->path, CAM_DEBUG_TRACE, ("xpt_schedule\n"));
 3642         device = perph->path->device;
 3643         if (periph_is_queued(perph)) {
 3644                 /* Simply reorder based on new priority */
 3645                 CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
 3646                           ("   change priority to %d\n", new_priority));
 3647                 if (new_priority < perph->pinfo.priority) {
 3648                         camq_change_priority(&device->drvq,
 3649                                              perph->pinfo.index,
 3650                                              new_priority);
 3651                 }
 3652                 runq = 0;
 3653         } else {
 3654                 /* New entry on the queue */
 3655                 CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
 3656                           ("   added periph to queue\n"));
 3657                 perph->pinfo.priority = new_priority;
 3658                 perph->pinfo.generation = ++device->drvq.generation;
 3659                 camq_insert(&device->drvq, &perph->pinfo);
 3660                 runq = xpt_schedule_dev_allocq(perph->path->bus, device);
 3661         }
 3662         if (runq != 0) {
 3663                 CAM_DEBUG(perph->path, CAM_DEBUG_SUBTRACE,
 3664                           ("   calling xpt_run_devq\n"));
 3665                 xpt_run_dev_allocq(perph->path->bus);
 3666         }
 3667 }
 3668 
 3669 
 3670 /*
 3671  * Schedule a device to run on a given queue.
 3672  * If the device was inserted as a new entry on the queue,
 3673  * return 1 meaning the device queue should be run. If we
 3674  * were already queued, implying someone else has already
 3675  * started the queue, return 0 so the caller doesn't attempt
 3676  * to run the queue.
 3677  */
 3678 static int
 3679 xpt_schedule_dev(struct camq *queue, cam_pinfo *pinfo,
 3680                  u_int32_t new_priority)
 3681 {
 3682         int retval;
 3683         u_int32_t old_priority;
 3684 
 3685         CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_schedule_dev\n"));
 3686 
 3687         old_priority = pinfo->priority;
 3688 
 3689         /*
 3690          * Are we already queued?
 3691          */
 3692         if (pinfo->index != CAM_UNQUEUED_INDEX) {
 3693                 /* Simply reorder based on new priority */
 3694                 if (new_priority < old_priority) {
 3695                         camq_change_priority(queue, pinfo->index,
 3696                                              new_priority);
 3697                         CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3698                                         ("changed priority to %d\n",
 3699                                          new_priority));
 3700                 }
 3701                 retval = 0;
 3702         } else {
 3703                 /* New entry on the queue */
 3704                 if (new_priority < old_priority)
 3705                         pinfo->priority = new_priority;
 3706 
 3707                 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3708                                 ("Inserting onto queue\n"));
 3709                 pinfo->generation = ++queue->generation;
 3710                 camq_insert(queue, pinfo);
 3711                 retval = 1;
 3712         }
 3713         return (retval);
 3714 }
 3715 
 3716 static void
 3717 xpt_run_dev_allocq(struct cam_eb *bus)
 3718 {
 3719         struct  cam_devq *devq;
 3720 
 3721         CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_allocq\n"));
 3722         devq = bus->sim->devq;
 3723 
 3724         CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3725                         ("   qfrozen_cnt == 0x%x, entries == %d, "
 3726                          "openings == %d, active == %d\n",
 3727                          devq->alloc_queue.qfrozen_cnt,
 3728                          devq->alloc_queue.entries,
 3729                          devq->alloc_openings,
 3730                          devq->alloc_active));
 3731 
 3732         devq->alloc_queue.qfrozen_cnt++;
 3733         while ((devq->alloc_queue.entries > 0)
 3734             && (devq->alloc_openings > 0)
 3735             && (devq->alloc_queue.qfrozen_cnt <= 1)) {
 3736                 struct  cam_ed_qinfo *qinfo;
 3737                 struct  cam_ed *device;
 3738                 union   ccb *work_ccb;
 3739                 struct  cam_periph *drv;
 3740                 struct  camq *drvq;
 3741 
 3742                 qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->alloc_queue,
 3743                                                            CAMQ_HEAD);
 3744                 device = qinfo->device;
 3745 
 3746                 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3747                                 ("running device %p\n", device));
 3748 
 3749                 drvq = &device->drvq;
 3750 
 3751 #ifdef CAMDEBUG
 3752                 if (drvq->entries <= 0) {
 3753                         panic("xpt_run_dev_allocq: "
 3754                               "Device on queue without any work to do");
 3755                 }
 3756 #endif
 3757                 if ((work_ccb = xpt_get_ccb(device)) != NULL) {
 3758                         devq->alloc_openings--;
 3759                         devq->alloc_active++;
 3760                         drv = (struct cam_periph*)camq_remove(drvq, CAMQ_HEAD);
 3761                         xpt_setup_ccb(&work_ccb->ccb_h, drv->path,
 3762                                       drv->pinfo.priority);
 3763                         CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3764                                         ("calling periph start\n"));
 3765                         drv->periph_start(drv, work_ccb);
 3766                 } else {
 3767                         /*
 3768                          * Malloc failure in alloc_ccb
 3769                          */
 3770                         /*
 3771                          * XXX add us to a list to be run from free_ccb
 3772                          * if we don't have any ccbs active on this
 3773                          * device queue otherwise we may never get run
 3774                          * again.
 3775                          */
 3776                         break;
 3777                 }
 3778 
 3779                 if (drvq->entries > 0) {
 3780                         /* We have more work.  Attempt to reschedule */
 3781                         xpt_schedule_dev_allocq(bus, device);
 3782                 }
 3783         }
 3784         devq->alloc_queue.qfrozen_cnt--;
 3785 }
 3786 
 3787 static void
 3788 xpt_run_dev_sendq(struct cam_eb *bus)
 3789 {
 3790         struct  cam_devq *devq;
 3791 
 3792         CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_run_dev_sendq\n"));
 3793 
 3794         devq = bus->sim->devq;
 3795 
 3796         devq->send_queue.qfrozen_cnt++;
 3797         while ((devq->send_queue.entries > 0)
 3798             && (devq->send_openings > 0)) {
 3799                 struct  cam_ed_qinfo *qinfo;
 3800                 struct  cam_ed *device;
 3801                 union ccb *work_ccb;
 3802                 struct  cam_sim *sim;
 3803 
 3804                 if (devq->send_queue.qfrozen_cnt > 1) {
 3805                         break;
 3806                 }
 3807 
 3808                 qinfo = (struct cam_ed_qinfo *)camq_remove(&devq->send_queue,
 3809                                                            CAMQ_HEAD);
 3810                 device = qinfo->device;
 3811 
 3812                 /*
 3813                  * If the device has been "frozen", don't attempt
 3814                  * to run it.
 3815                  */
 3816                 if (device->qfrozen_cnt > 0) {
 3817                         continue;
 3818                 }
 3819 
 3820                 CAM_DEBUG_PRINT(CAM_DEBUG_XPT,
 3821                                 ("running device %p\n", device));
 3822 
 3823                 work_ccb = cam_ccbq_peek_ccb(&device->ccbq, CAMQ_HEAD);
 3824                 if (work_ccb == NULL) {
 3825                         printf("device on run queue with no ccbs???\n");
 3826                         continue;
 3827                 }
 3828 
 3829                 if ((work_ccb->ccb_h.flags & CAM_HIGH_POWER) != 0) {
 3830 
 3831                         mtx_lock(&xsoftc.xpt_lock);
 3832                         if (xsoftc.num_highpower <= 0) {
 3833                                 /*
 3834                                  * We got a high power command, but we
 3835                                  * don't have any available slots.  Freeze
 3836                                  * the device queue until we have a slot
 3837                                  * available.
 3838                                  */
 3839                                 device->qfrozen_cnt++;
 3840                                 STAILQ_INSERT_TAIL(&xsoftc.highpowerq,
 3841                                                    &work_ccb->ccb_h,
 3842                                                    xpt_links.stqe);
 3843 
 3844                                 mtx_unlock(&xsoftc.xpt_lock);
 3845                                 continue;
 3846                         } else {
 3847                                 /*
 3848                                  * Consume a high power slot while
 3849                                  * this ccb runs.
 3850                                  */
 3851                                 xsoftc.num_highpower--;
 3852                         }
 3853                         mtx_unlock(&xsoftc.xpt_lock);
 3854                 }
 3855                 devq->active_dev = device;
 3856                 cam_ccbq_remove_ccb(&device->ccbq, work_ccb);
 3857 
 3858                 cam_ccbq_send_ccb(&device->ccbq, work_ccb);
 3859 
 3860                 devq->send_openings--;
 3861                 devq->send_active++;
 3862 
 3863                 if (device->ccbq.queue.entries > 0)
 3864                         xpt_schedule_dev_sendq(bus, device);
 3865 
 3866                 if (work_ccb && (work_ccb->ccb_h.flags & CAM_DEV_QFREEZE) != 0){
 3867                         /*
 3868                          * The client wants to freeze the queue
 3869                          * after this CCB is sent.
 3870                          */
 3871                         device->qfrozen_cnt++;
 3872                 }
 3873 
 3874                 /* In Target mode, the peripheral driver knows best... */
 3875                 if (work_ccb->ccb_h.func_code == XPT_SCSI_IO) {
 3876                         if ((device->inq_flags & SID_CmdQue) != 0
 3877                          && work_ccb->csio.tag_action != CAM_TAG_ACTION_NONE)
 3878                                 work_ccb->ccb_h.flags |= CAM_TAG_ACTION_VALID;
 3879                         else
 3880                                 /*
 3881                                  * Clear this in case of a retried CCB that
 3882                                  * failed due to a rejected tag.
 3883                                  */
 3884                                 work_ccb->ccb_h.flags &= ~CAM_TAG_ACTION_VALID;
 3885                 }
 3886 
 3887                 /*
 3888                  * Device queues can be shared among multiple sim instances
 3889                  * that reside on different busses.  Use the SIM in the queue
 3890                  * CCB's path, rather than the one in the bus that was passed
 3891                  * into this function.
 3892                  */
 3893                 sim = work_ccb->ccb_h.path->bus->sim;
 3894                 (*(sim->sim_action))(sim, work_ccb);
 3895 
 3896                 devq->active_dev = NULL;
 3897         }
 3898         devq->send_queue.qfrozen_cnt--;
 3899 }
 3900 
 3901 /*
 3902  * This function merges stuff from the slave ccb into the master ccb, while
 3903  * keeping important fields in the master ccb constant.
 3904  */
 3905 void
 3906 xpt_merge_ccb(union ccb *master_ccb, union ccb *slave_ccb)
 3907 {
 3908 
 3909         /*
 3910          * Pull fields that are valid for peripheral drivers to set
 3911          * into the master CCB along with the CCB "payload".
 3912          */
 3913         master_ccb->ccb_h.retry_count = slave_ccb->ccb_h.retry_count;
 3914         master_ccb->ccb_h.func_code = slave_ccb->ccb_h.func_code;
 3915         master_ccb->ccb_h.timeout = slave_ccb->ccb_h.timeout;
 3916         master_ccb->ccb_h.flags = slave_ccb->ccb_h.flags;
 3917         bcopy(&(&slave_ccb->ccb_h)[1], &(&master_ccb->ccb_h)[1],
 3918               sizeof(union ccb) - sizeof(struct ccb_hdr));
 3919 }
 3920 
 3921 void
 3922 xpt_setup_ccb(struct ccb_hdr *ccb_h, struct cam_path *path, u_int32_t priority)
 3923 {
 3924 
 3925         CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_setup_ccb\n"));
 3926         ccb_h->pinfo.priority = priority;
 3927         ccb_h->path = path;
 3928         ccb_h->path_id = path->bus->path_id;
 3929         if (path->target)
 3930                 ccb_h->target_id = path->target->target_id;
 3931         else
 3932                 ccb_h->target_id = CAM_TARGET_WILDCARD;
 3933         if (path->device) {
 3934                 ccb_h->target_lun = path->device->lun_id;
 3935                 ccb_h->pinfo.generation = ++path->device->ccbq.queue.generation;
 3936         } else {
 3937                 ccb_h->target_lun = CAM_TARGET_WILDCARD;
 3938         }
 3939         ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
 3940         ccb_h->flags = 0;
 3941 }
 3942 
 3943 /* Path manipulation functions */
 3944 cam_status
 3945 xpt_create_path(struct cam_path **new_path_ptr, struct cam_periph *perph,
 3946                 path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
 3947 {
 3948         struct     cam_path *path;
 3949         cam_status status;
 3950 
 3951         path = (struct cam_path *)malloc(sizeof(*path), M_CAMXPT, M_NOWAIT);
 3952 
 3953         if (path == NULL) {
 3954                 status = CAM_RESRC_UNAVAIL;
 3955                 return(status);
 3956         }
 3957         status = xpt_compile_path(path, perph, path_id, target_id, lun_id);
 3958         if (status != CAM_REQ_CMP) {
 3959                 free(path, M_CAMXPT);
 3960                 path = NULL;
 3961         }
 3962         *new_path_ptr = path;
 3963         return (status);
 3964 }
 3965 
 3966 cam_status
 3967 xpt_create_path_unlocked(struct cam_path **new_path_ptr,
 3968                          struct cam_periph *periph, path_id_t path_id,
 3969                          target_id_t target_id, lun_id_t lun_id)
 3970 {
 3971         struct     cam_path *path;
 3972         struct     cam_eb *bus = NULL;
 3973         cam_status status;
 3974         int        need_unlock = 0;
 3975 
 3976         path = (struct cam_path *)malloc(sizeof(*path), M_CAMXPT, M_WAITOK);
 3977 
 3978         if (path_id != CAM_BUS_WILDCARD) {
 3979                 bus = xpt_find_bus(path_id);
 3980                 if (bus != NULL) {
 3981                         need_unlock = 1;
 3982                         CAM_SIM_LOCK(bus->sim);
 3983                 }
 3984         }
 3985         status = xpt_compile_path(path, periph, path_id, target_id, lun_id);
 3986         if (need_unlock)
 3987                 CAM_SIM_UNLOCK(bus->sim);
 3988         if (status != CAM_REQ_CMP) {
 3989                 free(path, M_CAMXPT);
 3990                 path = NULL;
 3991         }
 3992         *new_path_ptr = path;
 3993         return (status);
 3994 }
 3995 
 3996 static cam_status
 3997 xpt_compile_path(struct cam_path *new_path, struct cam_periph *perph,
 3998                  path_id_t path_id, target_id_t target_id, lun_id_t lun_id)
 3999 {
 4000         struct       cam_eb *bus;
 4001         struct       cam_et *target;
 4002         struct       cam_ed *device;
 4003         cam_status   status;
 4004 
 4005         status = CAM_REQ_CMP;   /* Completed without error */
 4006         target = NULL;          /* Wildcarded */
 4007         device = NULL;          /* Wildcarded */
 4008 
 4009         /*
 4010          * We will potentially modify the EDT, so block interrupts
 4011          * that may attempt to create cam paths.
 4012          */
 4013         bus = xpt_find_bus(path_id);
 4014         if (bus == NULL) {
 4015                 status = CAM_PATH_INVALID;
 4016         } else {
 4017                 target = xpt_find_target(bus, target_id);
 4018                 if (target == NULL) {
 4019                         /* Create one */
 4020                         struct cam_et *new_target;
 4021 
 4022                         new_target = xpt_alloc_target(bus, target_id);
 4023                         if (new_target == NULL) {
 4024                                 status = CAM_RESRC_UNAVAIL;
 4025                         } else {
 4026                                 target = new_target;
 4027                         }
 4028                 }
 4029                 if (target != NULL) {
 4030                         device = xpt_find_device(target, lun_id);
 4031                         if (device == NULL) {
 4032                                 /* Create one */
 4033                                 struct cam_ed *new_device;
 4034 
 4035                                 new_device = xpt_alloc_device(bus,
 4036                                                               target,
 4037                                                               lun_id);
 4038                                 if (new_device == NULL) {
 4039                                         status = CAM_RESRC_UNAVAIL;
 4040                                 } else {
 4041                                         device = new_device;
 4042                                 }
 4043                         }
 4044                 }
 4045         }
 4046 
 4047         /*
 4048          * Only touch the user's data if we are successful.
 4049          */
 4050         if (status == CAM_REQ_CMP) {
 4051                 new_path->periph = perph;
 4052                 new_path->bus = bus;
 4053                 new_path->target = target;
 4054                 new_path->device = device;
 4055                 CAM_DEBUG(new_path, CAM_DEBUG_TRACE, ("xpt_compile_path\n"));
 4056         } else {
 4057                 if (device != NULL)
 4058                         xpt_release_device(bus, target, device);
 4059                 if (target != NULL)
 4060                         xpt_release_target(bus, target);
 4061                 if (bus != NULL)
 4062                         xpt_release_bus(bus);
 4063         }
 4064         return (status);
 4065 }
 4066 
 4067 static void
 4068 xpt_release_path(struct cam_path *path)
 4069 {
 4070         CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_release_path\n"));
 4071         if (path->device != NULL) {
 4072                 xpt_release_device(path->bus, path->target, path->device);
 4073                 path->device = NULL;
 4074         }
 4075         if (path->target != NULL) {
 4076                 xpt_release_target(path->bus, path->target);
 4077                 path->target = NULL;
 4078         }
 4079         if (path->bus != NULL) {
 4080                 xpt_release_bus(path->bus);
 4081                 path->bus = NULL;
 4082         }
 4083 }
 4084 
 4085 void
 4086 xpt_free_path(struct cam_path *path)
 4087 {
 4088 
 4089         CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_free_path\n"));
 4090         xpt_release_path(path);
 4091         free(path, M_CAMXPT);
 4092 }
 4093 
 4094 
 4095 /*
 4096  * Return -1 for failure, 0 for exact match, 1 for match with wildcards
 4097  * in path1, 2 for match with wildcards in path2.
 4098  */
 4099 int
 4100 xpt_path_comp(struct cam_path *path1, struct cam_path *path2)
 4101 {
 4102         int retval = 0;
 4103 
 4104         if (path1->bus != path2->bus) {
 4105                 if (path1->bus->path_id == CAM_BUS_WILDCARD)
 4106                         retval = 1;
 4107                 else if (path2->bus->path_id == CAM_BUS_WILDCARD)
 4108                         retval = 2;
 4109                 else
 4110                         return (-1);
 4111         }
 4112         if (path1->target != path2->target) {
 4113                 if (path1->target->target_id == CAM_TARGET_WILDCARD) {
 4114                         if (retval == 0)
 4115                                 retval = 1;
 4116                 } else if (path2->target->target_id == CAM_TARGET_WILDCARD)
 4117                         retval = 2;
 4118                 else
 4119                         return (-1);
 4120         }
 4121         if (path1->device != path2->device) {
 4122                 if (path1->device->lun_id == CAM_LUN_WILDCARD) {
 4123                         if (retval == 0)
 4124                                 retval = 1;
 4125                 } else if (path2->device->lun_id == CAM_LUN_WILDCARD)
 4126                         retval = 2;
 4127                 else
 4128                         return (-1);
 4129         }
 4130         return (retval);
 4131 }
 4132 
 4133 void
 4134 xpt_print_path(struct cam_path *path)
 4135 {
 4136 
 4137         if (path == NULL)
 4138                 printf("(nopath): ");
 4139         else {
 4140                 if (path->periph != NULL)
 4141                         printf("(%s%d:", path->periph->periph_name,
 4142                                path->periph->unit_number);
 4143                 else
 4144                         printf("(noperiph:");
 4145 
 4146                 if (path->bus != NULL)
 4147                         printf("%s%d:%d:", path->bus->sim->sim_name,
 4148                                path->bus->sim->unit_number,
 4149                                path->bus->sim->bus_id);
 4150                 else
 4151                         printf("nobus:");
 4152 
 4153                 if (path->target != NULL)
 4154                         printf("%d:", path->target->target_id);
 4155                 else
 4156                         printf("X:");
 4157 
 4158                 if (path->device != NULL)
 4159                         printf("%d): ", path->device->lun_id);
 4160                 else
 4161                         printf("X): ");
 4162         }
 4163 }
 4164 
 4165 void
 4166 xpt_print(struct cam_path *path, const char *fmt, ...)
 4167 {
 4168         va_list ap;
 4169         xpt_print_path(path);
 4170         va_start(ap, fmt);
 4171         vprintf(fmt, ap);
 4172         va_end(ap);
 4173 }
 4174 
 4175 int
 4176 xpt_path_string(struct cam_path *path, char *str, size_t str_len)
 4177 {
 4178         struct sbuf sb;
 4179 
 4180 #ifdef INVARIANTS
 4181         if (path != NULL && path->bus != NULL)
 4182                 mtx_assert(path->bus->sim->mtx, MA_OWNED);
 4183 #endif
 4184 
 4185         sbuf_new(&sb, str, str_len, 0);
 4186 
 4187         if (path == NULL)
 4188                 sbuf_printf(&sb, "(nopath): ");
 4189         else {
 4190                 if (path->periph != NULL)
 4191                         sbuf_printf(&sb, "(%s%d:", path->periph->periph_name,
 4192                                     path->periph->unit_number);
 4193                 else
 4194                         sbuf_printf(&sb, "(noperiph:");
 4195 
 4196                 if (path->bus != NULL)
 4197                         sbuf_printf(&sb, "%s%d:%d:", path->bus->sim->sim_name,
 4198                                     path->bus->sim->unit_number,
 4199                                     path->bus->sim->bus_id);
 4200                 else
 4201                         sbuf_printf(&sb, "nobus:");
 4202 
 4203                 if (path->target != NULL)
 4204                         sbuf_printf(&sb, "%d:", path->target->target_id);
 4205                 else
 4206                         sbuf_printf(&sb, "X:");
 4207 
 4208                 if (path->device != NULL)
 4209                         sbuf_printf(&sb, "%d): ", path->device->lun_id);
 4210                 else
 4211                         sbuf_printf(&sb, "X): ");
 4212         }
 4213         sbuf_finish(&sb);
 4214 
 4215         return(sbuf_len(&sb));
 4216 }
 4217 
 4218 path_id_t
 4219 xpt_path_path_id(struct cam_path *path)
 4220 {
 4221         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 4222 
 4223         return(path->bus->path_id);
 4224 }
 4225 
 4226 target_id_t
 4227 xpt_path_target_id(struct cam_path *path)
 4228 {
 4229         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 4230 
 4231         if (path->target != NULL)
 4232                 return (path->target->target_id);
 4233         else
 4234                 return (CAM_TARGET_WILDCARD);
 4235 }
 4236 
 4237 lun_id_t
 4238 xpt_path_lun_id(struct cam_path *path)
 4239 {
 4240         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 4241 
 4242         if (path->device != NULL)
 4243                 return (path->device->lun_id);
 4244         else
 4245                 return (CAM_LUN_WILDCARD);
 4246 }
 4247 
 4248 struct cam_sim *
 4249 xpt_path_sim(struct cam_path *path)
 4250 {
 4251 
 4252         return (path->bus->sim);
 4253 }
 4254 
 4255 struct cam_periph*
 4256 xpt_path_periph(struct cam_path *path)
 4257 {
 4258         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 4259 
 4260         return (path->periph);
 4261 }
 4262 
 4263 /*
 4264  * Release a CAM control block for the caller.  Remit the cost of the structure
 4265  * to the device referenced by the path.  If the this device had no 'credits'
 4266  * and peripheral drivers have registered async callbacks for this notification
 4267  * call them now.
 4268  */
 4269 void
 4270 xpt_release_ccb(union ccb *free_ccb)
 4271 {
 4272         struct   cam_path *path;
 4273         struct   cam_ed *device;
 4274         struct   cam_eb *bus;
 4275         struct   cam_sim *sim;
 4276 
 4277         CAM_DEBUG_PRINT(CAM_DEBUG_XPT, ("xpt_release_ccb\n"));
 4278         path = free_ccb->ccb_h.path;
 4279         device = path->device;
 4280         bus = path->bus;
 4281         sim = bus->sim;
 4282 
 4283         mtx_assert(sim->mtx, MA_OWNED);
 4284 
 4285         cam_ccbq_release_opening(&device->ccbq);
 4286         if (sim->ccb_count > sim->max_ccbs) {
 4287                 xpt_free_ccb(free_ccb);
 4288                 sim->ccb_count--;
 4289         } else {
 4290                 SLIST_INSERT_HEAD(&sim->ccb_freeq, &free_ccb->ccb_h,
 4291                     xpt_links.sle);
 4292         }
 4293         if (sim->devq == NULL) {
 4294                 return;
 4295         }
 4296         sim->devq->alloc_openings++;
 4297         sim->devq->alloc_active--;
 4298         /* XXX Turn this into an inline function - xpt_run_device?? */
 4299         if ((device_is_alloc_queued(device) == 0)
 4300          && (device->drvq.entries > 0)) {
 4301                 xpt_schedule_dev_allocq(bus, device);
 4302         }
 4303         if (dev_allocq_is_runnable(sim->devq))
 4304                 xpt_run_dev_allocq(bus);
 4305 }
 4306 
 4307 /* Functions accessed by SIM drivers */
 4308 
 4309 /*
 4310  * A sim structure, listing the SIM entry points and instance
 4311  * identification info is passed to xpt_bus_register to hook the SIM
 4312  * into the CAM framework.  xpt_bus_register creates a cam_eb entry
 4313  * for this new bus and places it in the array of busses and assigns
 4314  * it a path_id.  The path_id may be influenced by "hard wiring"
 4315  * information specified by the user.  Once interrupt services are
 4316  * available, the bus will be probed.
 4317  */
 4318 int32_t
 4319 xpt_bus_register(struct cam_sim *sim, device_t parent, u_int32_t bus)
 4320 {
 4321         struct cam_eb *new_bus;
 4322         struct cam_eb *old_bus;
 4323         struct ccb_pathinq cpi;
 4324 
 4325         mtx_assert(sim->mtx, MA_OWNED);
 4326 
 4327         sim->bus_id = bus;
 4328         new_bus = (struct cam_eb *)malloc(sizeof(*new_bus),
 4329                                           M_CAMXPT, M_NOWAIT);
 4330         if (new_bus == NULL) {
 4331                 /* Couldn't satisfy request */
 4332                 return (CAM_RESRC_UNAVAIL);
 4333         }
 4334 
 4335         if (strcmp(sim->sim_name, "xpt") != 0) {
 4336 
 4337                 sim->path_id =
 4338                     xptpathid(sim->sim_name, sim->unit_number, sim->bus_id);
 4339         }
 4340 
 4341         TAILQ_INIT(&new_bus->et_entries);
 4342         new_bus->path_id = sim->path_id;
 4343         cam_sim_hold(sim);
 4344         new_bus->sim = sim;
 4345         timevalclear(&new_bus->last_reset);
 4346         new_bus->flags = 0;
 4347         new_bus->refcount = 1;  /* Held until a bus_deregister event */
 4348         new_bus->generation = 0;
 4349         mtx_lock(&xsoftc.xpt_topo_lock);
 4350         old_bus = TAILQ_FIRST(&xsoftc.xpt_busses);
 4351         while (old_bus != NULL
 4352             && old_bus->path_id < new_bus->path_id)
 4353                 old_bus = TAILQ_NEXT(old_bus, links);
 4354         if (old_bus != NULL)
 4355                 TAILQ_INSERT_BEFORE(old_bus, new_bus, links);
 4356         else
 4357                 TAILQ_INSERT_TAIL(&xsoftc.xpt_busses, new_bus, links);
 4358         xsoftc.bus_generation++;
 4359         mtx_unlock(&xsoftc.xpt_topo_lock);
 4360 
 4361         /* Notify interested parties */
 4362         if (sim->path_id != CAM_XPT_PATH_ID) {
 4363                 struct cam_path path;
 4364 
 4365                 xpt_compile_path(&path, /*periph*/NULL, sim->path_id,
 4366                                  CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
 4367                 xpt_setup_ccb(&cpi.ccb_h, &path, /*priority*/1);
 4368                 cpi.ccb_h.func_code = XPT_PATH_INQ;
 4369                 xpt_action((union ccb *)&cpi);
 4370                 xpt_async(AC_PATH_REGISTERED, &path, &cpi);
 4371                 xpt_release_path(&path);
 4372         }
 4373         return (CAM_SUCCESS);
 4374 }
 4375 
 4376 int32_t
 4377 xpt_bus_deregister(path_id_t pathid)
 4378 {
 4379         struct cam_path bus_path;
 4380         cam_status status;
 4381 
 4382         status = xpt_compile_path(&bus_path, NULL, pathid,
 4383                                   CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
 4384         if (status != CAM_REQ_CMP)
 4385                 return (status);
 4386 
 4387         xpt_async(AC_LOST_DEVICE, &bus_path, NULL);
 4388         xpt_async(AC_PATH_DEREGISTERED, &bus_path, NULL);
 4389 
 4390         /* Release the reference count held while registered. */
 4391         xpt_release_bus(bus_path.bus);
 4392         xpt_release_path(&bus_path);
 4393 
 4394         return (CAM_REQ_CMP);
 4395 }
 4396 
 4397 static path_id_t
 4398 xptnextfreepathid(void)
 4399 {
 4400         struct cam_eb *bus;
 4401         path_id_t pathid;
 4402         const char *strval;
 4403 
 4404         pathid = 0;
 4405         mtx_lock(&xsoftc.xpt_topo_lock);
 4406         bus = TAILQ_FIRST(&xsoftc.xpt_busses);
 4407 retry:
 4408         /* Find an unoccupied pathid */
 4409         while (bus != NULL && bus->path_id <= pathid) {
 4410                 if (bus->path_id == pathid)
 4411                         pathid++;
 4412                 bus = TAILQ_NEXT(bus, links);
 4413         }
 4414         mtx_unlock(&xsoftc.xpt_topo_lock);
 4415 
 4416         /*
 4417          * Ensure that this pathid is not reserved for
 4418          * a bus that may be registered in the future.
 4419          */
 4420         if (resource_string_value("scbus", pathid, "at", &strval) == 0) {
 4421                 ++pathid;
 4422                 /* Start the search over */
 4423                 mtx_lock(&xsoftc.xpt_topo_lock);
 4424                 goto retry;
 4425         }
 4426         return (pathid);
 4427 }
 4428 
 4429 static path_id_t
 4430 xptpathid(const char *sim_name, int sim_unit, int sim_bus)
 4431 {
 4432         path_id_t pathid;
 4433         int i, dunit, val;
 4434         char buf[32];
 4435         const char *dname;
 4436 
 4437         pathid = CAM_XPT_PATH_ID;
 4438         snprintf(buf, sizeof(buf), "%s%d", sim_name, sim_unit);
 4439         i = 0;
 4440         while ((resource_find_match(&i, &dname, &dunit, "at", buf)) == 0) {
 4441                 if (strcmp(dname, "scbus")) {
 4442                         /* Avoid a bit of foot shooting. */
 4443                         continue;
 4444                 }
 4445                 if (dunit < 0)          /* unwired?! */
 4446                         continue;
 4447                 if (resource_int_value("scbus", dunit, "bus", &val) == 0) {
 4448                         if (sim_bus == val) {
 4449                                 pathid = dunit;
 4450                                 break;
 4451                         }
 4452                 } else if (sim_bus == 0) {
 4453                         /* Unspecified matches bus 0 */
 4454                         pathid = dunit;
 4455                         break;
 4456                 } else {
 4457                         printf("Ambiguous scbus configuration for %s%d "
 4458                                "bus %d, cannot wire down.  The kernel "
 4459                                "config entry for scbus%d should "
 4460                                "specify a controller bus.\n"
 4461                                "Scbus will be assigned dynamically.\n",
 4462                                sim_name, sim_unit, sim_bus, dunit);
 4463                         break;
 4464                 }
 4465         }
 4466 
 4467         if (pathid == CAM_XPT_PATH_ID)
 4468                 pathid = xptnextfreepathid();
 4469         return (pathid);
 4470 }
 4471 
 4472 void
 4473 xpt_async(u_int32_t async_code, struct cam_path *path, void *async_arg)
 4474 {
 4475         struct cam_eb *bus;
 4476         struct cam_et *target, *next_target;
 4477         struct cam_ed *device, *next_device;
 4478 
 4479         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 4480 
 4481         CAM_DEBUG(path, CAM_DEBUG_TRACE, ("xpt_async\n"));
 4482 
 4483         /*
 4484          * Most async events come from a CAM interrupt context.  In
 4485          * a few cases, the error recovery code at the peripheral layer,
 4486          * which may run from our SWI or a process context, may signal
 4487          * deferred events with a call to xpt_async.
 4488          */
 4489 
 4490         bus = path->bus;
 4491 
 4492         if (async_code == AC_BUS_RESET) {
 4493                 /* Update our notion of when the last reset occurred */
 4494                 microtime(&bus->last_reset);
 4495         }
 4496 
 4497         for (target = TAILQ_FIRST(&bus->et_entries);
 4498              target != NULL;
 4499              target = next_target) {
 4500 
 4501                 next_target = TAILQ_NEXT(target, links);
 4502 
 4503                 if (path->target != target
 4504                  && path->target->target_id != CAM_TARGET_WILDCARD
 4505                  && target->target_id != CAM_TARGET_WILDCARD)
 4506                         continue;
 4507 
 4508                 if (async_code == AC_SENT_BDR) {
 4509                         /* Update our notion of when the last reset occurred */
 4510                         microtime(&path->target->last_reset);
 4511                 }
 4512 
 4513                 for (device = TAILQ_FIRST(&target->ed_entries);
 4514                      device != NULL;
 4515                      device = next_device) {
 4516 
 4517                         next_device = TAILQ_NEXT(device, links);
 4518 
 4519                         if (path->device != device
 4520                          && path->device->lun_id != CAM_LUN_WILDCARD
 4521                          && device->lun_id != CAM_LUN_WILDCARD)
 4522                                 continue;
 4523 
 4524                         xpt_dev_async(async_code, bus, target,
 4525                                       device, async_arg);
 4526 
 4527                         xpt_async_bcast(&device->asyncs, async_code,
 4528                                         path, async_arg);
 4529                 }
 4530         }
 4531 
 4532         /*
 4533          * If this wasn't a fully wildcarded async, tell all
 4534          * clients that want all async events.
 4535          */
 4536         if (bus != xpt_periph->path->bus)
 4537                 xpt_async_bcast(&xpt_periph->path->device->asyncs, async_code,
 4538                                 path, async_arg);
 4539 }
 4540 
 4541 static void
 4542 xpt_async_bcast(struct async_list *async_head,
 4543                 u_int32_t async_code,
 4544                 struct cam_path *path, void *async_arg)
 4545 {
 4546         struct async_node *cur_entry;
 4547 
 4548         cur_entry = SLIST_FIRST(async_head);
 4549         while (cur_entry != NULL) {
 4550                 struct async_node *next_entry;
 4551                 /*
 4552                  * Grab the next list entry before we call the current
 4553                  * entry's callback.  This is because the callback function
 4554                  * can delete its async callback entry.
 4555                  */
 4556                 next_entry = SLIST_NEXT(cur_entry, links);
 4557                 if ((cur_entry->event_enable & async_code) != 0)
 4558                         cur_entry->callback(cur_entry->callback_arg,
 4559                                             async_code, path,
 4560                                             async_arg);
 4561                 cur_entry = next_entry;
 4562         }
 4563 }
 4564 
 4565 /*
 4566  * Handle any per-device event notifications that require action by the XPT.
 4567  */
 4568 static void
 4569 xpt_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
 4570               struct cam_ed *device, void *async_arg)
 4571 {
 4572         cam_status status;
 4573         struct cam_path newpath;
 4574 
 4575         /*
 4576          * We only need to handle events for real devices.
 4577          */
 4578         if (target->target_id == CAM_TARGET_WILDCARD
 4579          || device->lun_id == CAM_LUN_WILDCARD)
 4580                 return;
 4581 
 4582         /*
 4583          * We need our own path with wildcards expanded to
 4584          * handle certain types of events.
 4585          */
 4586         if ((async_code == AC_SENT_BDR)
 4587          || (async_code == AC_BUS_RESET)
 4588          || (async_code == AC_INQ_CHANGED))
 4589                 status = xpt_compile_path(&newpath, NULL,
 4590                                           bus->path_id,
 4591                                           target->target_id,
 4592                                           device->lun_id);
 4593         else
 4594                 status = CAM_REQ_CMP_ERR;
 4595 
 4596         if (status == CAM_REQ_CMP) {
 4597 
 4598                 /*
 4599                  * Allow transfer negotiation to occur in a
 4600                  * tag free environment.
 4601                  */
 4602                 if (async_code == AC_SENT_BDR
 4603                  || async_code == AC_BUS_RESET)
 4604                         xpt_toggle_tags(&newpath);
 4605 
 4606                 if (async_code == AC_INQ_CHANGED) {
 4607                         /*
 4608                          * We've sent a start unit command, or
 4609                          * something similar to a device that
 4610                          * may have caused its inquiry data to
 4611                          * change. So we re-scan the device to
 4612                          * refresh the inquiry data for it.
 4613                          */
 4614                         xpt_scan_lun(newpath.periph, &newpath,
 4615                                      CAM_EXPECT_INQ_CHANGE, NULL);
 4616                 }
 4617                 xpt_release_path(&newpath);
 4618         } else if (async_code == AC_LOST_DEVICE) {
 4619                 device->flags |= CAM_DEV_UNCONFIGURED;
 4620         } else if (async_code == AC_TRANSFER_NEG) {
 4621                 struct ccb_trans_settings *settings;
 4622 
 4623                 settings = (struct ccb_trans_settings *)async_arg;
 4624                 xpt_set_transfer_settings(settings, device,
 4625                                           /*async_update*/TRUE);
 4626         }
 4627 }
 4628 
 4629 u_int32_t
 4630 xpt_freeze_devq(struct cam_path *path, u_int count)
 4631 {
 4632         struct ccb_hdr *ccbh;
 4633 
 4634         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 4635 
 4636         path->device->qfrozen_cnt += count;
 4637 
 4638         /*
 4639          * Mark the last CCB in the queue as needing
 4640          * to be requeued if the driver hasn't
 4641          * changed it's state yet.  This fixes a race
 4642          * where a ccb is just about to be queued to
 4643          * a controller driver when it's interrupt routine
 4644          * freezes the queue.  To completly close the
 4645          * hole, controller drives must check to see
 4646          * if a ccb's status is still CAM_REQ_INPROG
 4647          * just before they queue
 4648          * the CCB.  See ahc_action/ahc_freeze_devq for
 4649          * an example.
 4650          */
 4651         ccbh = TAILQ_LAST(&path->device->ccbq.active_ccbs, ccb_hdr_tailq);
 4652         if (ccbh && ccbh->status == CAM_REQ_INPROG)
 4653                 ccbh->status = CAM_REQUEUE_REQ;
 4654         return (path->device->qfrozen_cnt);
 4655 }
 4656 
 4657 u_int32_t
 4658 xpt_freeze_simq(struct cam_sim *sim, u_int count)
 4659 {
 4660         mtx_assert(sim->mtx, MA_OWNED);
 4661 
 4662         sim->devq->send_queue.qfrozen_cnt += count;
 4663         if (sim->devq->active_dev != NULL) {
 4664                 struct ccb_hdr *ccbh;
 4665 
 4666                 ccbh = TAILQ_LAST(&sim->devq->active_dev->ccbq.active_ccbs,
 4667                                   ccb_hdr_tailq);
 4668                 if (ccbh && ccbh->status == CAM_REQ_INPROG)
 4669                         ccbh->status = CAM_REQUEUE_REQ;
 4670         }
 4671         return (sim->devq->send_queue.qfrozen_cnt);
 4672 }
 4673 
 4674 static void
 4675 xpt_release_devq_timeout(void *arg)
 4676 {
 4677         struct cam_ed *device;
 4678 
 4679         device = (struct cam_ed *)arg;
 4680 
 4681         xpt_release_devq_device(device, /*count*/1, /*run_queue*/TRUE);
 4682 }
 4683 
 4684 void
 4685 xpt_release_devq(struct cam_path *path, u_int count, int run_queue)
 4686 {
 4687         mtx_assert(path->bus->sim->mtx, MA_OWNED);
 4688 
 4689         xpt_release_devq_device(path->device, count, run_queue);
 4690 }
 4691 
 4692 static void
 4693 xpt_release_devq_device(struct cam_ed *dev, u_int count, int run_queue)
 4694 {
 4695         int     rundevq;
 4696 
 4697         rundevq = 0;
 4698         if (dev->qfrozen_cnt > 0) {
 4699 
 4700                 count = (count > dev->qfrozen_cnt) ? dev->qfrozen_cnt : count;
 4701                 dev->qfrozen_cnt -= count;
 4702                 if (dev->qfrozen_cnt == 0) {
 4703 
 4704                         /*
 4705                          * No longer need to wait for a successful
 4706                          * command completion.
 4707                          */
 4708                         dev->flags &= ~CAM_DEV_REL_ON_COMPLETE;
 4709 
 4710                         /*
 4711                          * Remove any timeouts that might be scheduled
 4712                          * to release this queue.
 4713                          */
 4714                         if ((dev->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0) {
 4715                                 callout_stop(&dev->callout);
 4716                                 dev->flags &= ~CAM_DEV_REL_TIMEOUT_PENDING;
 4717                         }
 4718 
 4719                         /*
 4720                          * Now that we are unfrozen schedule the
 4721                          * device so any pending transactions are
 4722                          * run.
 4723                          */
 4724                         if ((dev->ccbq.queue.entries > 0)
 4725                          && (xpt_schedule_dev_sendq(dev->target->bus, dev))
 4726                          && (run_queue != 0)) {
 4727                                 rundevq = 1;
 4728                         }
 4729                 }
 4730         }
 4731         if (rundevq != 0)
 4732                 xpt_run_dev_sendq(dev->target->bus);
 4733 }
 4734 
 4735 void
 4736 xpt_release_simq(struct cam_sim *sim, int run_queue)
 4737 {
 4738         struct  camq *sendq;
 4739 
 4740         mtx_assert(sim->mtx, MA_OWNED);
 4741 
 4742         sendq = &(sim->devq->send_queue);
 4743         if (sendq->qfrozen_cnt > 0) {
 4744 
 4745                 sendq->qfrozen_cnt--;
 4746                 if (sendq->qfrozen_cnt == 0) {
 4747                         struct cam_eb *bus;
 4748 
 4749                         /*
 4750                          * If there is a timeout scheduled to release this
 4751                          * sim queue, remove it.  The queue frozen count is
 4752                          * already at 0.
 4753                          */
 4754                         if ((sim->flags & CAM_SIM_REL_TIMEOUT_PENDING) != 0){
 4755                                 callout_stop(&sim->callout);
 4756                                 sim->flags &= ~CAM_SIM_REL_TIMEOUT_PENDING;
 4757                         }
 4758                         bus = xpt_find_bus(sim->path_id);
 4759 
 4760                         if (run_queue) {
 4761                                 /*
 4762                                  * Now that we are unfrozen run the send queue.
 4763                                  */
 4764                                 xpt_run_dev_sendq(bus);
 4765                         }
 4766                         xpt_release_bus(bus);
 4767                 }
 4768         }
 4769 }
 4770 
 4771 /*
 4772  * XXX Appears to be unused.
 4773  */
 4774 static void
 4775 xpt_release_simq_timeout(void *arg)
 4776 {
 4777         struct cam_sim *sim;
 4778 
 4779         sim = (struct cam_sim *)arg;
 4780         xpt_release_simq(sim, /* run_queue */ TRUE);
 4781 }
 4782 
 4783 void
 4784 xpt_done(union ccb *done_ccb)
 4785 {
 4786         struct cam_sim *sim;
 4787 
 4788         CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xpt_done\n"));
 4789         if ((done_ccb->ccb_h.func_code & XPT_FC_QUEUED) != 0) {
 4790                 /*
 4791                  * Queue up the request for handling by our SWI handler
 4792                  * any of the "non-immediate" type of ccbs.
 4793                  */
 4794                 sim = done_ccb->ccb_h.path->bus->sim;
 4795                 switch (done_ccb->ccb_h.path->periph->type) {
 4796                 case CAM_PERIPH_BIO:
 4797                         TAILQ_INSERT_TAIL(&sim->sim_doneq, &done_ccb->ccb_h,
 4798                                           sim_links.tqe);
 4799                         done_ccb->ccb_h.pinfo.index = CAM_DONEQ_INDEX;
 4800                         if ((sim->flags & CAM_SIM_ON_DONEQ) == 0) {
 4801                                 mtx_lock(&cam_simq_lock);
 4802                                 TAILQ_INSERT_TAIL(&cam_simq, sim,
 4803                                                   links);
 4804                                 sim->flags |= CAM_SIM_ON_DONEQ;
 4805                                 mtx_unlock(&cam_simq_lock);
 4806                         }
 4807                         if ((done_ccb->ccb_h.path->periph->flags &
 4808                             CAM_PERIPH_POLLED) == 0)
 4809                                 swi_sched(cambio_ih, 0);
 4810                         break;
 4811                 default:
 4812                         panic("unknown periph type %d",
 4813                             done_ccb->ccb_h.path->periph->type);
 4814                 }
 4815         }
 4816 }
 4817 
 4818 union ccb *
 4819 xpt_alloc_ccb()
 4820 {
 4821         union ccb *new_ccb;
 4822 
 4823         new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_ZERO|M_WAITOK);
 4824         return (new_ccb);
 4825 }
 4826 
 4827 union ccb *
 4828 xpt_alloc_ccb_nowait()
 4829 {
 4830         union ccb *new_ccb;
 4831 
 4832         new_ccb = malloc(sizeof(*new_ccb), M_CAMXPT, M_ZERO|M_NOWAIT);
 4833         return (new_ccb);
 4834 }
 4835 
 4836 void
 4837 xpt_free_ccb(union ccb *free_ccb)
 4838 {
 4839         free(free_ccb, M_CAMXPT);
 4840 }
 4841 
 4842 
 4843 
 4844 /* Private XPT functions */
 4845 
 4846 /*
 4847  * Get a CAM control block for the caller. Charge the structure to the device
 4848  * referenced by the path.  If the this device has no 'credits' then the
 4849  * device already has the maximum number of outstanding operations under way
 4850  * and we return NULL. If we don't have sufficient resources to allocate more
 4851  * ccbs, we also return NULL.
 4852  */
 4853 static union ccb *
 4854 xpt_get_ccb(struct cam_ed *device)
 4855 {
 4856         union ccb *new_ccb;
 4857         struct cam_sim *sim;
 4858 
 4859         sim = device->sim;
 4860         if ((new_ccb = (union ccb *)SLIST_FIRST(&sim->ccb_freeq)) == NULL) {
 4861                 new_ccb = xpt_alloc_ccb_nowait();
 4862                 if (new_ccb == NULL) {
 4863                         return (NULL);
 4864                 }
 4865                 if ((sim->flags & CAM_SIM_MPSAFE) == 0)
 4866                         callout_handle_init(&new_ccb->ccb_h.timeout_ch);
 4867                 SLIST_INSERT_HEAD(&sim->ccb_freeq, &new_ccb->ccb_h,
 4868                                   xpt_links.sle);
 4869                 sim->ccb_count++;
 4870         }
 4871         cam_ccbq_take_opening(&device->ccbq);
 4872         SLIST_REMOVE_HEAD(&sim->ccb_freeq, xpt_links.sle);
 4873         return (new_ccb);
 4874 }
 4875 
 4876 static void
 4877 xpt_release_bus(struct cam_eb *bus)
 4878 {
 4879 
 4880         if ((--bus->refcount == 0)
 4881          && (TAILQ_FIRST(&bus->et_entries) == NULL)) {
 4882                 mtx_lock(&xsoftc.xpt_topo_lock);
 4883                 TAILQ_REMOVE(&xsoftc.xpt_busses, bus, links);
 4884                 xsoftc.bus_generation++;
 4885                 mtx_unlock(&xsoftc.xpt_topo_lock);
 4886                 cam_sim_release(bus->sim);
 4887                 free(bus, M_CAMXPT);
 4888         }
 4889 }
 4890 
 4891 static struct cam_et *
 4892 xpt_alloc_target(struct cam_eb *bus, target_id_t target_id)
 4893 {
 4894         struct cam_et *target;
 4895 
 4896         target = (struct cam_et *)malloc(sizeof(*target), M_CAMXPT, M_NOWAIT);
 4897         if (target != NULL) {
 4898                 struct cam_et *cur_target;
 4899 
 4900                 TAILQ_INIT(&target->ed_entries);
 4901                 target->bus = bus;
 4902                 target->target_id = target_id;
 4903                 target->refcount = 1;
 4904                 target->generation = 0;
 4905                 timevalclear(&target->last_reset);
 4906                 /*
 4907                  * Hold a reference to our parent bus so it
 4908                  * will not go away before we do.
 4909                  */
 4910                 bus->refcount++;
 4911 
 4912                 /* Insertion sort into our bus's target list */
 4913                 cur_target = TAILQ_FIRST(&bus->et_entries);
 4914                 while (cur_target != NULL && cur_target->target_id < target_id)
 4915                         cur_target = TAILQ_NEXT(cur_target, links);
 4916 
 4917                 if (cur_target != NULL) {
 4918                         TAILQ_INSERT_BEFORE(cur_target, target, links);
 4919                 } else {
 4920                         TAILQ_INSERT_TAIL(&bus->et_entries, target, links);
 4921                 }
 4922                 bus->generation++;
 4923         }
 4924         return (target);
 4925 }
 4926 
 4927 static void
 4928 xpt_release_target(struct cam_eb *bus, struct cam_et *target)
 4929 {
 4930 
 4931         if ((--target->refcount == 0)
 4932          && (TAILQ_FIRST(&target->ed_entries) == NULL)) {
 4933                 TAILQ_REMOVE(&bus->et_entries, target, links);
 4934                 bus->generation++;
 4935                 free(target, M_CAMXPT);
 4936                 xpt_release_bus(bus);
 4937         }
 4938 }
 4939 
 4940 static struct cam_ed *
 4941 xpt_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
 4942 {
 4943         struct     cam_path path;
 4944         struct     cam_ed *device;
 4945         struct     cam_devq *devq;
 4946         cam_status status;
 4947 
 4948         /* Make space for us in the device queue on our bus */
 4949         devq = bus->sim->devq;
 4950         status = cam_devq_resize(devq, devq->alloc_queue.array_size + 1);
 4951 
 4952         if (status != CAM_REQ_CMP) {
 4953                 device = NULL;
 4954         } else {
 4955                 device = (struct cam_ed *)malloc(sizeof(*device),
 4956                                                  M_CAMXPT, M_NOWAIT);
 4957         }
 4958 
 4959         if (device != NULL) {
 4960                 struct cam_ed *cur_device;
 4961 
 4962                 cam_init_pinfo(&device->alloc_ccb_entry.pinfo);
 4963                 device->alloc_ccb_entry.device = device;
 4964                 cam_init_pinfo(&device->send_ccb_entry.pinfo);
 4965                 device->send_ccb_entry.device = device;
 4966                 device->target = target;
 4967                 device->lun_id = lun_id;
 4968                 device->sim = bus->sim;
 4969                 /* Initialize our queues */
 4970                 if (camq_init(&device->drvq, 0) != 0) {
 4971                         free(device, M_CAMXPT);
 4972                         return (NULL);
 4973                 }
 4974                 if (cam_ccbq_init(&device->ccbq,
 4975                                   bus->sim->max_dev_openings) != 0) {
 4976                         camq_fini(&device->drvq);
 4977                         free(device, M_CAMXPT);
 4978                         return (NULL);
 4979                 }
 4980                 SLIST_INIT(&device->asyncs);
 4981                 SLIST_INIT(&device->periphs);
 4982                 device->generation = 0;
 4983                 device->owner = NULL;
 4984                 /*
 4985                  * Take the default quirk entry until we have inquiry
 4986                  * data and can determine a better quirk to use.
 4987                  */
 4988                 device->quirk = &xpt_quirk_table[xpt_quirk_table_size - 1];
 4989                 bzero(&device->inq_data, sizeof(device->inq_data));
 4990                 device->inq_flags = 0;
 4991                 device->queue_flags = 0;
 4992                 device->serial_num = NULL;
 4993                 device->serial_num_len = 0;
 4994                 device->qfrozen_cnt = 0;
 4995                 device->flags = CAM_DEV_UNCONFIGURED;
 4996                 device->tag_delay_count = 0;
 4997                 device->tag_saved_openings = 0;
 4998                 device->refcount = 1;
 4999                 if (bus->sim->flags & CAM_SIM_MPSAFE)
 5000                         callout_init_mtx(&device->callout, bus->sim->mtx, 0);
 5001                 else
 5002                         callout_init_mtx(&device->callout, &Giant, 0);
 5003 
 5004                 /*
 5005                  * Hold a reference to our parent target so it
 5006                  * will not go away before we do.
 5007                  */
 5008                 target->refcount++;
 5009 
 5010                 /*
 5011                  * XXX should be limited by number of CCBs this bus can
 5012                  * do.
 5013                  */
 5014                 bus->sim->max_ccbs += device->ccbq.devq_openings;
 5015                 /* Insertion sort into our target's device list */
 5016                 cur_device = TAILQ_FIRST(&target->ed_entries);
 5017                 while (cur_device != NULL && cur_device->lun_id < lun_id)
 5018                         cur_device = TAILQ_NEXT(cur_device, links);
 5019                 if (cur_device != NULL) {
 5020                         TAILQ_INSERT_BEFORE(cur_device, device, links);
 5021                 } else {
 5022                         TAILQ_INSERT_TAIL(&target->ed_entries, device, links);
 5023                 }
 5024                 target->generation++;
 5025                 if (lun_id != CAM_LUN_WILDCARD) {
 5026                         xpt_compile_path(&path,
 5027                                          NULL,
 5028                                          bus->path_id,
 5029                                          target->target_id,
 5030                                          lun_id);
 5031                         xpt_devise_transport(&path);
 5032                         xpt_release_path(&path);
 5033                 }
 5034         }
 5035         return (device);
 5036 }
 5037 
 5038 static void
 5039 xpt_release_device(struct cam_eb *bus, struct cam_et *target,
 5040                    struct cam_ed *device)
 5041 {
 5042 
 5043         if ((--device->refcount == 0)
 5044          && ((device->flags & CAM_DEV_UNCONFIGURED) != 0)) {
 5045                 struct cam_devq *devq;
 5046 
 5047                 if (device->alloc_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX
 5048                  || device->send_ccb_entry.pinfo.index != CAM_UNQUEUED_INDEX)
 5049                         panic("Removing device while still queued for ccbs");
 5050 
 5051                 if ((device->flags & CAM_DEV_REL_TIMEOUT_PENDING) != 0)
 5052                                 callout_stop(&device->callout);
 5053 
 5054                 TAILQ_REMOVE(&target->ed_entries, device,links);
 5055                 target->generation++;
 5056                 bus->sim->max_ccbs -= device->ccbq.devq_openings;
 5057                 /* Release our slot in the devq */
 5058                 devq = bus->sim->devq;
 5059                 cam_devq_resize(devq, devq->alloc_queue.array_size - 1);
 5060                 camq_fini(&device->drvq);
 5061                 camq_fini(&device->ccbq.queue);
 5062                 free(device, M_CAMXPT);
 5063                 xpt_release_target(bus, target);
 5064         }
 5065 }
 5066 
 5067 static u_int32_t
 5068 xpt_dev_ccbq_resize(struct cam_path *path, int newopenings)
 5069 {
 5070         int     diff;
 5071         int     result;
 5072         struct  cam_ed *dev;
 5073 
 5074         dev = path->device;
 5075 
 5076         diff = newopenings - (dev->ccbq.dev_active + dev->ccbq.dev_openings);
 5077         result = cam_ccbq_resize(&dev->ccbq, newopenings);
 5078         if (result == CAM_REQ_CMP && (diff < 0)) {
 5079                 dev->flags |= CAM_DEV_RESIZE_QUEUE_NEEDED;
 5080         }
 5081         if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
 5082          || (dev->inq_flags & SID_CmdQue) != 0)
 5083                 dev->tag_saved_openings = newopenings;
 5084         /* Adjust the global limit */
 5085         dev->sim->max_ccbs += diff;
 5086         return (result);
 5087 }
 5088 
 5089 static struct cam_eb *
 5090 xpt_find_bus(path_id_t path_id)
 5091 {
 5092         struct cam_eb *bus;
 5093 
 5094         mtx_lock(&xsoftc.xpt_topo_lock);
 5095         for (bus = TAILQ_FIRST(&xsoftc.xpt_busses);
 5096              bus != NULL;
 5097              bus = TAILQ_NEXT(bus, links)) {
 5098                 if (bus->path_id == path_id) {
 5099                         bus->refcount++;
 5100                         break;
 5101                 }
 5102         }
 5103         mtx_unlock(&xsoftc.xpt_topo_lock);
 5104         return (bus);
 5105 }
 5106 
 5107 static struct cam_et *
 5108 xpt_find_target(struct cam_eb *bus, target_id_t target_id)
 5109 {
 5110         struct cam_et *target;
 5111 
 5112         for (target = TAILQ_FIRST(&bus->et_entries);
 5113              target != NULL;
 5114              target = TAILQ_NEXT(target, links)) {
 5115                 if (target->target_id == target_id) {
 5116                         target->refcount++;
 5117                         break;
 5118                 }
 5119         }
 5120         return (target);
 5121 }
 5122 
 5123 static struct cam_ed *
 5124 xpt_find_device(struct cam_et *target, lun_id_t lun_id)
 5125 {
 5126         struct cam_ed *device;
 5127 
 5128         for (device = TAILQ_FIRST(&target->ed_entries);
 5129              device != NULL;
 5130              device = TAILQ_NEXT(device, links)) {
 5131                 if (device->lun_id == lun_id) {
 5132                         device->refcount++;
 5133                         break;
 5134                 }
 5135         }
 5136         return (device);
 5137 }
 5138 
 5139 typedef struct {
 5140         union   ccb *request_ccb;
 5141         struct  ccb_pathinq *cpi;
 5142         int     counter;
 5143 } xpt_scan_bus_info;
 5144 
 5145 /*
 5146  * To start a scan, request_ccb is an XPT_SCAN_BUS ccb.
 5147  * As the scan progresses, xpt_scan_bus is used as the
 5148  * callback on completion function.
 5149  */
 5150 static void
 5151 xpt_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
 5152 {
 5153         CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
 5154                   ("xpt_scan_bus\n"));
 5155         switch (request_ccb->ccb_h.func_code) {
 5156         case XPT_SCAN_BUS:
 5157         {
 5158                 xpt_scan_bus_info *scan_info;
 5159                 union   ccb *work_ccb;
 5160                 struct  cam_path *path;
 5161                 u_int   i;
 5162                 u_int   max_target;
 5163                 u_int   initiator_id;
 5164 
 5165                 /* Find out the characteristics of the bus */
 5166                 work_ccb = xpt_alloc_ccb_nowait();
 5167                 if (work_ccb == NULL) {
 5168                         request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 5169                         xpt_done(request_ccb);
 5170                         return;
 5171                 }
 5172                 xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path,
 5173                               request_ccb->ccb_h.pinfo.priority);
 5174                 work_ccb->ccb_h.func_code = XPT_PATH_INQ;
 5175                 xpt_action(work_ccb);
 5176                 if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
 5177                         request_ccb->ccb_h.status = work_ccb->ccb_h.status;
 5178                         xpt_free_ccb(work_ccb);
 5179                         xpt_done(request_ccb);
 5180                         return;
 5181                 }
 5182 
 5183                 if ((work_ccb->cpi.hba_misc & PIM_NOINITIATOR) != 0) {
 5184                         /*
 5185                          * Can't scan the bus on an adapter that
 5186                          * cannot perform the initiator role.
 5187                          */
 5188                         request_ccb->ccb_h.status = CAM_REQ_CMP;
 5189                         xpt_free_ccb(work_ccb);
 5190                         xpt_done(request_ccb);
 5191                         return;
 5192                 }
 5193 
 5194                 /* Save some state for use while we probe for devices */
 5195                 scan_info = (xpt_scan_bus_info *)
 5196                     malloc(sizeof(xpt_scan_bus_info), M_CAMXPT, M_NOWAIT);
 5197                 if (scan_info == NULL) {
 5198                         request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 5199                         xpt_done(request_ccb);
 5200                         return;
 5201                 }
 5202                 scan_info->request_ccb = request_ccb;
 5203                 scan_info->cpi = &work_ccb->cpi;
 5204 
 5205                 /* Cache on our stack so we can work asynchronously */
 5206                 max_target = scan_info->cpi->max_target;
 5207                 initiator_id = scan_info->cpi->initiator_id;
 5208 
 5209 
 5210                 /*
 5211                  * We can scan all targets in parallel, or do it sequentially.
 5212                  */
 5213                 if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
 5214                         max_target = 0;
 5215                         scan_info->counter = 0;
 5216                 } else {
 5217                         scan_info->counter = scan_info->cpi->max_target + 1;
 5218                         if (scan_info->cpi->initiator_id < scan_info->counter) {
 5219                                 scan_info->counter--;
 5220                         }
 5221                 }
 5222 
 5223                 for (i = 0; i <= max_target; i++) {
 5224                         cam_status status;
 5225                         if (i == initiator_id)
 5226                                 continue;
 5227 
 5228                         status = xpt_create_path(&path, xpt_periph,
 5229                                                  request_ccb->ccb_h.path_id,
 5230                                                  i, 0);
 5231                         if (status != CAM_REQ_CMP) {
 5232                                 printf("xpt_scan_bus: xpt_create_path failed"
 5233                                        " with status %#x, bus scan halted\n",
 5234                                        status);
 5235                                 free(scan_info, M_CAMXPT);
 5236                                 request_ccb->ccb_h.status = status;
 5237                                 xpt_free_ccb(work_ccb);
 5238                                 xpt_done(request_ccb);
 5239                                 break;
 5240                         }
 5241                         work_ccb = xpt_alloc_ccb_nowait();
 5242                         if (work_ccb == NULL) {
 5243                                 xpt_free_ccb((union ccb *)scan_info->cpi);
 5244                                 free(scan_info, M_CAMXPT);
 5245                                 xpt_free_path(path);
 5246                                 request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 5247                                 xpt_done(request_ccb);
 5248                                 break;
 5249                         }
 5250                         xpt_setup_ccb(&work_ccb->ccb_h, path,
 5251                                       request_ccb->ccb_h.pinfo.priority);
 5252                         work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
 5253                         work_ccb->ccb_h.cbfcnp = xpt_scan_bus;
 5254                         work_ccb->ccb_h.ppriv_ptr0 = scan_info;
 5255                         work_ccb->crcn.flags = request_ccb->crcn.flags;
 5256                         xpt_action(work_ccb);
 5257                 }
 5258                 break;
 5259         }
 5260         case XPT_SCAN_LUN:
 5261         {
 5262                 cam_status status;
 5263                 struct cam_path *path;
 5264                 xpt_scan_bus_info *scan_info;
 5265                 path_id_t path_id;
 5266                 target_id_t target_id;
 5267                 lun_id_t lun_id;
 5268 
 5269                 /* Reuse the same CCB to query if a device was really found */
 5270                 scan_info = (xpt_scan_bus_info *)request_ccb->ccb_h.ppriv_ptr0;
 5271                 xpt_setup_ccb(&request_ccb->ccb_h, request_ccb->ccb_h.path,
 5272                               request_ccb->ccb_h.pinfo.priority);
 5273                 request_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 5274 
 5275                 path_id = request_ccb->ccb_h.path_id;
 5276                 target_id = request_ccb->ccb_h.target_id;
 5277                 lun_id = request_ccb->ccb_h.target_lun;
 5278                 xpt_action(request_ccb);
 5279 
 5280                 if (request_ccb->ccb_h.status != CAM_REQ_CMP) {
 5281                         struct cam_ed *device;
 5282                         struct cam_et *target;
 5283                         int phl;
 5284 
 5285                         /*
 5286                          * If we already probed lun 0 successfully, or
 5287                          * we have additional configured luns on this
 5288                          * target that might have "gone away", go onto
 5289                          * the next lun.
 5290                          */
 5291                         target = request_ccb->ccb_h.path->target;
 5292                         /*
 5293                          * We may touch devices that we don't
 5294                          * hold references too, so ensure they
 5295                          * don't disappear out from under us.
 5296                          * The target above is referenced by the
 5297                          * path in the request ccb.
 5298                          */
 5299                         phl = 0;
 5300                         device = TAILQ_FIRST(&target->ed_entries);
 5301                         if (device != NULL) {
 5302                                 phl = CAN_SRCH_HI_SPARSE(device);
 5303                                 if (device->lun_id == 0)
 5304                                         device = TAILQ_NEXT(device, links);
 5305                         }
 5306                         if ((lun_id != 0) || (device != NULL)) {
 5307                                 if (lun_id < (CAM_SCSI2_MAXLUN-1) || phl)
 5308                                         lun_id++;
 5309                         }
 5310                 } else {
 5311                         struct cam_ed *device;
 5312 
 5313                         device = request_ccb->ccb_h.path->device;
 5314 
 5315                         if ((device->quirk->quirks & CAM_QUIRK_NOLUNS) == 0) {
 5316                                 /* Try the next lun */
 5317                                 if (lun_id < (CAM_SCSI2_MAXLUN-1)
 5318                                   || CAN_SRCH_HI_DENSE(device))
 5319                                         lun_id++;
 5320                         }
 5321                 }
 5322 
 5323                 /*
 5324                  * Free the current request path- we're done with it.
 5325                  */
 5326                 xpt_free_path(request_ccb->ccb_h.path);
 5327 
 5328                 /*
 5329                  * Check to see if we scan any further luns.
 5330                  */
 5331                 if (lun_id == request_ccb->ccb_h.target_lun
 5332                  || lun_id > scan_info->cpi->max_lun) {
 5333                         int done;
 5334 
 5335  hop_again:
 5336                         done = 0;
 5337                         if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
 5338                                 scan_info->counter++;
 5339                                 if (scan_info->counter ==
 5340                                     scan_info->cpi->initiator_id) {
 5341                                         scan_info->counter++;
 5342                                 }
 5343                                 if (scan_info->counter >=
 5344                                     scan_info->cpi->max_target+1) {
 5345                                         done = 1;
 5346                                 }
 5347                         } else {
 5348                                 scan_info->counter--;
 5349                                 if (scan_info->counter == 0) {
 5350                                         done = 1;
 5351                                 }
 5352                         }
 5353                         if (done) {
 5354                                 xpt_free_ccb(request_ccb);
 5355                                 xpt_free_ccb((union ccb *)scan_info->cpi);
 5356                                 request_ccb = scan_info->request_ccb;
 5357                                 free(scan_info, M_CAMXPT);
 5358                                 request_ccb->ccb_h.status = CAM_REQ_CMP;
 5359                                 xpt_done(request_ccb);
 5360                                 break;
 5361                         }
 5362 
 5363                         if ((scan_info->cpi->hba_misc & PIM_SEQSCAN) == 0) {
 5364                                 xpt_free_ccb(request_ccb);
 5365                                 break;
 5366                         }
 5367                         status = xpt_create_path(&path, xpt_periph,
 5368                             scan_info->request_ccb->ccb_h.path_id,
 5369                             scan_info->counter, 0);
 5370                         if (status != CAM_REQ_CMP) {
 5371                                 printf("xpt_scan_bus: xpt_create_path failed"
 5372                                     " with status %#x, bus scan halted\n",
 5373                                     status);
 5374                                 xpt_free_ccb(request_ccb);
 5375                                 xpt_free_ccb((union ccb *)scan_info->cpi);
 5376                                 request_ccb = scan_info->request_ccb;
 5377                                 free(scan_info, M_CAMXPT);
 5378                                 request_ccb->ccb_h.status = status;
 5379                                 xpt_done(request_ccb);
 5380                                 break;
 5381                         }
 5382                         xpt_setup_ccb(&request_ccb->ccb_h, path,
 5383                             request_ccb->ccb_h.pinfo.priority);
 5384                         request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
 5385                         request_ccb->ccb_h.cbfcnp = xpt_scan_bus;
 5386                         request_ccb->ccb_h.ppriv_ptr0 = scan_info;
 5387                         request_ccb->crcn.flags =
 5388                             scan_info->request_ccb->crcn.flags;
 5389                 } else {
 5390                         status = xpt_create_path(&path, xpt_periph,
 5391                                                  path_id, target_id, lun_id);
 5392                         if (status != CAM_REQ_CMP) {
 5393                                 printf("xpt_scan_bus: xpt_create_path failed "
 5394                                        "with status %#x, halting LUN scan\n",
 5395                                        status);
 5396                                 goto hop_again;
 5397                         }
 5398                         xpt_setup_ccb(&request_ccb->ccb_h, path,
 5399                                       request_ccb->ccb_h.pinfo.priority);
 5400                         request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
 5401                         request_ccb->ccb_h.cbfcnp = xpt_scan_bus;
 5402                         request_ccb->ccb_h.ppriv_ptr0 = scan_info;
 5403                         request_ccb->crcn.flags =
 5404                                 scan_info->request_ccb->crcn.flags;
 5405                 }
 5406                 xpt_action(request_ccb);
 5407                 break;
 5408         }
 5409         default:
 5410                 break;
 5411         }
 5412 }
 5413 
 5414 typedef enum {
 5415         PROBE_TUR,
 5416         PROBE_INQUIRY,  /* this counts as DV0 for Basic Domain Validation */
 5417         PROBE_FULL_INQUIRY,
 5418         PROBE_MODE_SENSE,
 5419         PROBE_SERIAL_NUM_0,
 5420         PROBE_SERIAL_NUM_1,
 5421         PROBE_TUR_FOR_NEGOTIATION,
 5422         PROBE_INQUIRY_BASIC_DV1,
 5423         PROBE_INQUIRY_BASIC_DV2,
 5424         PROBE_DV_EXIT,
 5425         PROBE_INVALID
 5426 } probe_action;
 5427 
 5428 static char *probe_action_text[] = {
 5429         "PROBE_TUR",
 5430         "PROBE_INQUIRY",
 5431         "PROBE_FULL_INQUIRY",
 5432         "PROBE_MODE_SENSE",
 5433         "PROBE_SERIAL_NUM_0",
 5434         "PROBE_SERIAL_NUM_1",
 5435         "PROBE_TUR_FOR_NEGOTIATION",
 5436         "PROBE_INQUIRY_BASIC_DV1",
 5437         "PROBE_INQUIRY_BASIC_DV2",
 5438         "PROBE_DV_EXIT",
 5439         "PROBE_INVALID"
 5440 };
 5441 
 5442 #define PROBE_SET_ACTION(softc, newaction)      \
 5443 do {                                                                    \
 5444         char **text;                                                    \
 5445         text = probe_action_text;                                       \
 5446         CAM_DEBUG((softc)->periph->path, CAM_DEBUG_INFO,                \
 5447             ("Probe %s to %s\n", text[(softc)->action],                 \
 5448             text[(newaction)]));                                        \
 5449         (softc)->action = (newaction);                                  \
 5450 } while(0)
 5451 
 5452 typedef enum {
 5453         PROBE_INQUIRY_CKSUM     = 0x01,
 5454         PROBE_SERIAL_CKSUM      = 0x02,
 5455         PROBE_NO_ANNOUNCE       = 0x04
 5456 } probe_flags;
 5457 
 5458 typedef struct {
 5459         TAILQ_HEAD(, ccb_hdr) request_ccbs;
 5460         probe_action    action;
 5461         union ccb       saved_ccb;
 5462         probe_flags     flags;
 5463         MD5_CTX         context;
 5464         u_int8_t        digest[16];
 5465         struct cam_periph *periph;
 5466 } probe_softc;
 5467 
 5468 static void
 5469 xpt_scan_lun(struct cam_periph *periph, struct cam_path *path,
 5470              cam_flags flags, union ccb *request_ccb)
 5471 {
 5472         struct ccb_pathinq cpi;
 5473         cam_status status;
 5474         struct cam_path *new_path;
 5475         struct cam_periph *old_periph;
 5476 
 5477         CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
 5478                   ("xpt_scan_lun\n"));
 5479 
 5480         xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
 5481         cpi.ccb_h.func_code = XPT_PATH_INQ;
 5482         xpt_action((union ccb *)&cpi);
 5483 
 5484         if (cpi.ccb_h.status != CAM_REQ_CMP) {
 5485                 if (request_ccb != NULL) {
 5486                         request_ccb->ccb_h.status = cpi.ccb_h.status;
 5487                         xpt_done(request_ccb);
 5488                 }
 5489                 return;
 5490         }
 5491 
 5492         if ((cpi.hba_misc & PIM_NOINITIATOR) != 0) {
 5493                 /*
 5494                  * Can't scan the bus on an adapter that
 5495                  * cannot perform the initiator role.
 5496                  */
 5497                 if (request_ccb != NULL) {
 5498                         request_ccb->ccb_h.status = CAM_REQ_CMP;
 5499                         xpt_done(request_ccb);
 5500                 }
 5501                 return;
 5502         }
 5503 
 5504         if (request_ccb == NULL) {
 5505                 request_ccb = malloc(sizeof(union ccb), M_CAMXPT, M_NOWAIT);
 5506                 if (request_ccb == NULL) {
 5507                         xpt_print(path, "xpt_scan_lun: can't allocate CCB, "
 5508                             "can't continue\n");
 5509                         return;
 5510                 }
 5511                 new_path = malloc(sizeof(*new_path), M_CAMXPT, M_NOWAIT);
 5512                 if (new_path == NULL) {
 5513                         xpt_print(path, "xpt_scan_lun: can't allocate path, "
 5514                             "can't continue\n");
 5515                         free(request_ccb, M_CAMXPT);
 5516                         return;
 5517                 }
 5518                 status = xpt_compile_path(new_path, xpt_periph,
 5519                                           path->bus->path_id,
 5520                                           path->target->target_id,
 5521                                           path->device->lun_id);
 5522 
 5523                 if (status != CAM_REQ_CMP) {
 5524                         xpt_print(path, "xpt_scan_lun: can't compile path, "
 5525                             "can't continue\n");
 5526                         free(request_ccb, M_CAMXPT);
 5527                         free(new_path, M_CAMXPT);
 5528                         return;
 5529                 }
 5530                 xpt_setup_ccb(&request_ccb->ccb_h, new_path, /*priority*/ 1);
 5531                 request_ccb->ccb_h.cbfcnp = xptscandone;
 5532                 request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
 5533                 request_ccb->crcn.flags = flags;
 5534         }
 5535 
 5536         if ((old_periph = cam_periph_find(path, "probe")) != NULL) {
 5537                 probe_softc *softc;
 5538 
 5539                 softc = (probe_softc *)old_periph->softc;
 5540                 TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
 5541                                   periph_links.tqe);
 5542         } else {
 5543                 status = cam_periph_alloc(proberegister, NULL, probecleanup,
 5544                                           probestart, "probe",
 5545                                           CAM_PERIPH_BIO,
 5546                                           request_ccb->ccb_h.path, NULL, 0,
 5547                                           request_ccb);
 5548 
 5549                 if (status != CAM_REQ_CMP) {
 5550                         xpt_print(path, "xpt_scan_lun: cam_alloc_periph "
 5551                             "returned an error, can't continue probe\n");
 5552                         request_ccb->ccb_h.status = status;
 5553                         xpt_done(request_ccb);
 5554                 }
 5555         }
 5556 }
 5557 
 5558 static void
 5559 xptscandone(struct cam_periph *periph, union ccb *done_ccb)
 5560 {
 5561         xpt_release_path(done_ccb->ccb_h.path);
 5562         free(done_ccb->ccb_h.path, M_CAMXPT);
 5563         free(done_ccb, M_CAMXPT);
 5564 }
 5565 
 5566 static cam_status
 5567 proberegister(struct cam_periph *periph, void *arg)
 5568 {
 5569         union ccb *request_ccb; /* CCB representing the probe request */
 5570         cam_status status;
 5571         probe_softc *softc;
 5572 
 5573         request_ccb = (union ccb *)arg;
 5574         if (periph == NULL) {
 5575                 printf("proberegister: periph was NULL!!\n");
 5576                 return(CAM_REQ_CMP_ERR);
 5577         }
 5578 
 5579         if (request_ccb == NULL) {
 5580                 printf("proberegister: no probe CCB, "
 5581                        "can't register device\n");
 5582                 return(CAM_REQ_CMP_ERR);
 5583         }
 5584 
 5585         softc = (probe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_NOWAIT);
 5586 
 5587         if (softc == NULL) {
 5588                 printf("proberegister: Unable to probe new device. "
 5589                        "Unable to allocate softc\n");
 5590                 return(CAM_REQ_CMP_ERR);
 5591         }
 5592         TAILQ_INIT(&softc->request_ccbs);
 5593         TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
 5594                           periph_links.tqe);
 5595         softc->flags = 0;
 5596         periph->softc = softc;
 5597         softc->periph = periph;
 5598         softc->action = PROBE_INVALID;
 5599         status = cam_periph_acquire(periph);
 5600         if (status != CAM_REQ_CMP) {
 5601                 return (status);
 5602         }
 5603 
 5604 
 5605         /*
 5606          * Ensure we've waited at least a bus settle
 5607          * delay before attempting to probe the device.
 5608          * For HBAs that don't do bus resets, this won't make a difference.
 5609          */
 5610         cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset,
 5611                                       scsi_delay);
 5612         probeschedule(periph);
 5613         return(CAM_REQ_CMP);
 5614 }
 5615 
 5616 static void
 5617 probeschedule(struct cam_periph *periph)
 5618 {
 5619         struct ccb_pathinq cpi;
 5620         union ccb *ccb;
 5621         probe_softc *softc;
 5622 
 5623         softc = (probe_softc *)periph->softc;
 5624         ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
 5625 
 5626         xpt_setup_ccb(&cpi.ccb_h, periph->path, /*priority*/1);
 5627         cpi.ccb_h.func_code = XPT_PATH_INQ;
 5628         xpt_action((union ccb *)&cpi);
 5629 
 5630         /*
 5631          * If a device has gone away and another device, or the same one,
 5632          * is back in the same place, it should have a unit attention
 5633          * condition pending.  It will not report the unit attention in
 5634          * response to an inquiry, which may leave invalid transfer
 5635          * negotiations in effect.  The TUR will reveal the unit attention
 5636          * condition.  Only send the TUR for lun 0, since some devices
 5637          * will get confused by commands other than inquiry to non-existent
 5638          * luns.  If you think a device has gone away start your scan from
 5639          * lun 0.  This will insure that any bogus transfer settings are
 5640          * invalidated.
 5641          *
 5642          * If we haven't seen the device before and the controller supports
 5643          * some kind of transfer negotiation, negotiate with the first
 5644          * sent command if no bus reset was performed at startup.  This
 5645          * ensures that the device is not confused by transfer negotiation
 5646          * settings left over by loader or BIOS action.
 5647          */
 5648         if (((ccb->ccb_h.path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
 5649          && (ccb->ccb_h.target_lun == 0)) {
 5650                 PROBE_SET_ACTION(softc, PROBE_TUR);
 5651         } else if ((cpi.hba_inquiry & (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) != 0
 5652               && (cpi.hba_misc & PIM_NOBUSRESET) != 0) {
 5653                 proberequestdefaultnegotiation(periph);
 5654                 PROBE_SET_ACTION(softc, PROBE_INQUIRY);
 5655         } else {
 5656                 PROBE_SET_ACTION(softc, PROBE_INQUIRY);
 5657         }
 5658 
 5659         if (ccb->crcn.flags & CAM_EXPECT_INQ_CHANGE)
 5660                 softc->flags |= PROBE_NO_ANNOUNCE;
 5661         else
 5662                 softc->flags &= ~PROBE_NO_ANNOUNCE;
 5663 
 5664         xpt_schedule(periph, ccb->ccb_h.pinfo.priority);
 5665 }
 5666 
 5667 static void
 5668 probestart(struct cam_periph *periph, union ccb *start_ccb)
 5669 {
 5670         /* Probe the device that our peripheral driver points to */
 5671         struct ccb_scsiio *csio;
 5672         probe_softc *softc;
 5673 
 5674         CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
 5675 
 5676         softc = (probe_softc *)periph->softc;
 5677         csio = &start_ccb->csio;
 5678 
 5679         switch (softc->action) {
 5680         case PROBE_TUR:
 5681         case PROBE_TUR_FOR_NEGOTIATION:
 5682         case PROBE_DV_EXIT:
 5683         {
 5684                 scsi_test_unit_ready(csio,
 5685                                      /*retries*/10,
 5686                                      probedone,
 5687                                      MSG_SIMPLE_Q_TAG,
 5688                                      SSD_FULL_SIZE,
 5689                                      /*timeout*/60000);
 5690                 break;
 5691         }
 5692         case PROBE_INQUIRY:
 5693         case PROBE_FULL_INQUIRY:
 5694         case PROBE_INQUIRY_BASIC_DV1:
 5695         case PROBE_INQUIRY_BASIC_DV2:
 5696         {
 5697                 u_int inquiry_len;
 5698                 struct scsi_inquiry_data *inq_buf;
 5699 
 5700                 inq_buf = &periph->path->device->inq_data;
 5701 
 5702                 /*
 5703                  * If the device is currently configured, we calculate an
 5704                  * MD5 checksum of the inquiry data, and if the serial number
 5705                  * length is greater than 0, add the serial number data
 5706                  * into the checksum as well.  Once the inquiry and the
 5707                  * serial number check finish, we attempt to figure out
 5708                  * whether we still have the same device.
 5709                  */
 5710                 if ((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0) {
 5711 
 5712                         MD5Init(&softc->context);
 5713                         MD5Update(&softc->context, (unsigned char *)inq_buf,
 5714                                   sizeof(struct scsi_inquiry_data));
 5715                         softc->flags |= PROBE_INQUIRY_CKSUM;
 5716                         if (periph->path->device->serial_num_len > 0) {
 5717                                 MD5Update(&softc->context,
 5718                                           periph->path->device->serial_num,
 5719                                           periph->path->device->serial_num_len);
 5720                                 softc->flags |= PROBE_SERIAL_CKSUM;
 5721                         }
 5722                         MD5Final(softc->digest, &softc->context);
 5723                 }
 5724 
 5725                 if (softc->action == PROBE_INQUIRY)
 5726                         inquiry_len = SHORT_INQUIRY_LENGTH;
 5727                 else
 5728                         inquiry_len = SID_ADDITIONAL_LENGTH(inq_buf);
 5729 
 5730                 /*
 5731                  * Some parallel SCSI devices fail to send an
 5732                  * ignore wide residue message when dealing with
 5733                  * odd length inquiry requests.  Round up to be
 5734                  * safe.
 5735                  */
 5736                 inquiry_len = roundup2(inquiry_len, 2);
 5737 
 5738                 if (softc->action == PROBE_INQUIRY_BASIC_DV1
 5739                  || softc->action == PROBE_INQUIRY_BASIC_DV2) {
 5740                         inq_buf = malloc(inquiry_len, M_CAMXPT, M_NOWAIT);
 5741                 }
 5742                 if (inq_buf == NULL) {
 5743                         xpt_print(periph->path, "malloc failure- skipping Basic"
 5744                             "Domain Validation\n");
 5745                         PROBE_SET_ACTION(softc, PROBE_DV_EXIT);
 5746                         scsi_test_unit_ready(csio,
 5747                                              /*retries*/4,
 5748                                              probedone,
 5749                                              MSG_SIMPLE_Q_TAG,
 5750                                              SSD_FULL_SIZE,
 5751                                              /*timeout*/60000);
 5752                         break;
 5753                 }
 5754                 scsi_inquiry(csio,
 5755                              /*retries*/4,
 5756                              probedone,
 5757                              MSG_SIMPLE_Q_TAG,
 5758                              (u_int8_t *)inq_buf,
 5759                              inquiry_len,
 5760                              /*evpd*/FALSE,
 5761                              /*page_code*/0,
 5762                              SSD_MIN_SIZE,
 5763                              /*timeout*/60 * 1000);
 5764                 break;
 5765         }
 5766         case PROBE_MODE_SENSE:
 5767         {
 5768                 void  *mode_buf;
 5769                 int    mode_buf_len;
 5770 
 5771                 mode_buf_len = sizeof(struct scsi_mode_header_6)
 5772                              + sizeof(struct scsi_mode_blk_desc)
 5773                              + sizeof(struct scsi_control_page);
 5774                 mode_buf = malloc(mode_buf_len, M_CAMXPT, M_NOWAIT);
 5775                 if (mode_buf != NULL) {
 5776                         scsi_mode_sense(csio,
 5777                                         /*retries*/4,
 5778                                         probedone,
 5779                                         MSG_SIMPLE_Q_TAG,
 5780                                         /*dbd*/FALSE,
 5781                                         SMS_PAGE_CTRL_CURRENT,
 5782                                         SMS_CONTROL_MODE_PAGE,
 5783                                         mode_buf,
 5784                                         mode_buf_len,
 5785                                         SSD_FULL_SIZE,
 5786                                         /*timeout*/60000);
 5787                         break;
 5788                 }
 5789                 xpt_print(periph->path, "Unable to mode sense control page - "
 5790                     "malloc failure\n");
 5791                 PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
 5792         }
 5793         /* FALLTHROUGH */
 5794         case PROBE_SERIAL_NUM_0:
 5795         {
 5796                 struct scsi_vpd_supported_page_list *vpd_list = NULL;
 5797                 struct cam_ed *device;
 5798 
 5799                 device = periph->path->device;
 5800                 if ((device->quirk->quirks & CAM_QUIRK_NOSERIAL) == 0) {
 5801                         vpd_list = malloc(sizeof(*vpd_list), M_CAMXPT,
 5802                             M_NOWAIT | M_ZERO);
 5803                 }
 5804 
 5805                 if (vpd_list != NULL) {
 5806                         scsi_inquiry(csio,
 5807                                      /*retries*/4,
 5808                                      probedone,
 5809                                      MSG_SIMPLE_Q_TAG,
 5810                                      (u_int8_t *)vpd_list,
 5811                                      sizeof(*vpd_list),
 5812                                      /*evpd*/TRUE,
 5813                                      SVPD_SUPPORTED_PAGE_LIST,
 5814                                      SSD_MIN_SIZE,
 5815                                      /*timeout*/60 * 1000);
 5816                         break;
 5817                 }
 5818                 /*
 5819                  * We'll have to do without, let our probedone
 5820                  * routine finish up for us.
 5821                  */
 5822                 start_ccb->csio.data_ptr = NULL;
 5823                 probedone(periph, start_ccb);
 5824                 return;
 5825         }
 5826         case PROBE_SERIAL_NUM_1:
 5827         {
 5828                 struct scsi_vpd_unit_serial_number *serial_buf;
 5829                 struct cam_ed* device;
 5830 
 5831                 serial_buf = NULL;
 5832                 device = periph->path->device;
 5833                 if (device->serial_num != NULL) {
 5834                         free(device->serial_num, M_CAMXPT);
 5835                         device->serial_num = NULL;
 5836                         device->serial_num_len = 0;
 5837                 }
 5838 
 5839                 serial_buf = (struct scsi_vpd_unit_serial_number *)
 5840                         malloc(sizeof(*serial_buf), M_CAMXPT, M_NOWAIT|M_ZERO);
 5841 
 5842                 if (serial_buf != NULL) {
 5843                         scsi_inquiry(csio,
 5844                                      /*retries*/4,
 5845                                      probedone,
 5846                                      MSG_SIMPLE_Q_TAG,
 5847                                      (u_int8_t *)serial_buf,
 5848                                      sizeof(*serial_buf),
 5849                                      /*evpd*/TRUE,
 5850                                      SVPD_UNIT_SERIAL_NUMBER,
 5851                                      SSD_MIN_SIZE,
 5852                                      /*timeout*/60 * 1000);
 5853                         break;
 5854                 }
 5855                 /*
 5856                  * We'll have to do without, let our probedone
 5857                  * routine finish up for us.
 5858                  */
 5859                 start_ccb->csio.data_ptr = NULL;
 5860                 probedone(periph, start_ccb);
 5861                 return;
 5862         }
 5863         case PROBE_INVALID:
 5864                 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO,
 5865                     ("probestart: invalid action state\n"));
 5866         default:
 5867                 break;
 5868         }
 5869         xpt_action(start_ccb);
 5870 }
 5871 
 5872 static void
 5873 proberequestdefaultnegotiation(struct cam_periph *periph)
 5874 {
 5875         struct ccb_trans_settings cts;
 5876 
 5877         xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
 5878         cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 5879         cts.type = CTS_TYPE_USER_SETTINGS;
 5880         xpt_action((union ccb *)&cts);
 5881         if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 5882                 return;
 5883         }
 5884         cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
 5885         cts.type = CTS_TYPE_CURRENT_SETTINGS;
 5886         xpt_action((union ccb *)&cts);
 5887 }
 5888 
 5889 /*
 5890  * Backoff Negotiation Code- only pertinent for SPI devices.
 5891  */
 5892 static int
 5893 proberequestbackoff(struct cam_periph *periph, struct cam_ed *device)
 5894 {
 5895         struct ccb_trans_settings cts;
 5896         struct ccb_trans_settings_spi *spi;
 5897 
 5898         memset(&cts, 0, sizeof (cts));
 5899         xpt_setup_ccb(&cts.ccb_h, periph->path, /*priority*/1);
 5900         cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 5901         cts.type = CTS_TYPE_CURRENT_SETTINGS;
 5902         xpt_action((union ccb *)&cts);
 5903         if ((cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 5904                 if (bootverbose) {
 5905                         xpt_print(periph->path,
 5906                             "failed to get current device settings\n");
 5907                 }
 5908                 return (0);
 5909         }
 5910         if (cts.transport != XPORT_SPI) {
 5911                 if (bootverbose) {
 5912                         xpt_print(periph->path, "not SPI transport\n");
 5913                 }
 5914                 return (0);
 5915         }
 5916         spi = &cts.xport_specific.spi;
 5917 
 5918         /*
 5919          * We cannot renegotiate sync rate if we don't have one.
 5920          */
 5921         if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
 5922                 if (bootverbose) {
 5923                         xpt_print(periph->path, "no sync rate known\n");
 5924                 }
 5925                 return (0);
 5926         }
 5927 
 5928         /*
 5929          * We'll assert that we don't have to touch PPR options- the
 5930          * SIM will see what we do with period and offset and adjust
 5931          * the PPR options as appropriate.
 5932          */
 5933 
 5934         /*
 5935          * A sync rate with unknown or zero offset is nonsensical.
 5936          * A sync period of zero means Async.
 5937          */
 5938         if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0
 5939          || spi->sync_offset == 0 || spi->sync_period == 0) {
 5940                 if (bootverbose) {
 5941                         xpt_print(periph->path, "no sync rate available\n");
 5942                 }
 5943                 return (0);
 5944         }
 5945 
 5946         if (device->flags & CAM_DEV_DV_HIT_BOTTOM) {
 5947                 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
 5948                     ("hit async: giving up on DV\n"));
 5949                 return (0);
 5950         }
 5951 
 5952 
 5953         /*
 5954          * Jump sync_period up by one, but stop at 5MHz and fall back to Async.
 5955          * We don't try to remember 'last' settings to see if the SIM actually
 5956          * gets into the speed we want to set. We check on the SIM telling
 5957          * us that a requested speed is bad, but otherwise don't try and
 5958          * check the speed due to the asynchronous and handshake nature
 5959          * of speed setting.
 5960          */
 5961         spi->valid = CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_SYNC_OFFSET;
 5962         for (;;) {
 5963                 spi->sync_period++;
 5964                 if (spi->sync_period >= 0xf) {
 5965                         spi->sync_period = 0;
 5966                         spi->sync_offset = 0;
 5967                         CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
 5968                             ("setting to async for DV\n"));
 5969                         /*
 5970                          * Once we hit async, we don't want to try
 5971                          * any more settings.
 5972                          */
 5973                         device->flags |= CAM_DEV_DV_HIT_BOTTOM;
 5974                 } else if (bootverbose) {
 5975                         CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
 5976                             ("DV: period 0x%x\n", spi->sync_period));
 5977                         printf("setting period to 0x%x\n", spi->sync_period);
 5978                 }
 5979                 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
 5980                 cts.type = CTS_TYPE_CURRENT_SETTINGS;
 5981                 xpt_action((union ccb *)&cts);
 5982                 if ((cts.ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 5983                         break;
 5984                 }
 5985                 CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
 5986                     ("DV: failed to set period 0x%x\n", spi->sync_period));
 5987                 if (spi->sync_period == 0) {
 5988                         return (0);
 5989                 }
 5990         }
 5991         return (1);
 5992 }
 5993 
 5994 static void
 5995 probedone(struct cam_periph *periph, union ccb *done_ccb)
 5996 {
 5997         probe_softc *softc;
 5998         struct cam_path *path;
 5999         u_int32_t  priority;
 6000 
 6001         CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
 6002 
 6003         softc = (probe_softc *)periph->softc;
 6004         path = done_ccb->ccb_h.path;
 6005         priority = done_ccb->ccb_h.pinfo.priority;
 6006 
 6007         switch (softc->action) {
 6008         case PROBE_TUR:
 6009         {
 6010                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 6011 
 6012                         if (cam_periph_error(done_ccb, 0,
 6013                                              SF_NO_PRINT, NULL) == ERESTART)
 6014                                 return;
 6015                         else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
 6016                                 /* Don't wedge the queue */
 6017                                 xpt_release_devq(done_ccb->ccb_h.path,
 6018                                                  /*count*/1,
 6019                                                  /*run_queue*/TRUE);
 6020                 }
 6021                 PROBE_SET_ACTION(softc, PROBE_INQUIRY);
 6022                 xpt_release_ccb(done_ccb);
 6023                 xpt_schedule(periph, priority);
 6024                 return;
 6025         }
 6026         case PROBE_INQUIRY:
 6027         case PROBE_FULL_INQUIRY:
 6028         {
 6029                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 6030                         struct scsi_inquiry_data *inq_buf;
 6031                         u_int8_t periph_qual;
 6032 
 6033                         path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
 6034                         inq_buf = &path->device->inq_data;
 6035 
 6036                         periph_qual = SID_QUAL(inq_buf);
 6037 
 6038                         switch(periph_qual) {
 6039                         case SID_QUAL_LU_CONNECTED:
 6040                         {
 6041                                 u_int8_t len;
 6042 
 6043                                 /*
 6044                                  * We conservatively request only
 6045                                  * SHORT_INQUIRY_LEN bytes of inquiry
 6046                                  * information during our first try
 6047                                  * at sending an INQUIRY. If the device
 6048                                  * has more information to give,
 6049                                  * perform a second request specifying
 6050                                  * the amount of information the device
 6051                                  * is willing to give.
 6052                                  */
 6053                                 len = inq_buf->additional_length
 6054                                     + offsetof(struct scsi_inquiry_data,
 6055                                                additional_length) + 1;
 6056                                 if (softc->action == PROBE_INQUIRY
 6057                                     && len > SHORT_INQUIRY_LENGTH) {
 6058                                         PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
 6059                                         xpt_release_ccb(done_ccb);
 6060                                         xpt_schedule(periph, priority);
 6061                                         return;
 6062                                 }
 6063 
 6064                                 xpt_find_quirk(path->device);
 6065 
 6066                                 xpt_devise_transport(path);
 6067                                 if (INQ_DATA_TQ_ENABLED(inq_buf))
 6068                                         PROBE_SET_ACTION(softc, PROBE_MODE_SENSE);
 6069                                 else
 6070                                         PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
 6071 
 6072                                 path->device->flags &= ~CAM_DEV_UNCONFIGURED;
 6073 
 6074                                 xpt_release_ccb(done_ccb);
 6075                                 xpt_schedule(periph, priority);
 6076                                 return;
 6077                         }
 6078                         default:
 6079                                 break;
 6080                         }
 6081                 } else if (cam_periph_error(done_ccb, 0,
 6082                                             done_ccb->ccb_h.target_lun > 0
 6083                                             ? SF_RETRY_UA|SF_QUIET_IR
 6084                                             : SF_RETRY_UA,
 6085                                             &softc->saved_ccb) == ERESTART) {
 6086                         return;
 6087                 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 6088                         /* Don't wedge the queue */
 6089                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 6090                                          /*run_queue*/TRUE);
 6091                 }
 6092                 /*
 6093                  * If we get to this point, we got an error status back
 6094                  * from the inquiry and the error status doesn't require
 6095                  * automatically retrying the command.  Therefore, the
 6096                  * inquiry failed.  If we had inquiry information before
 6097                  * for this device, but this latest inquiry command failed,
 6098                  * the device has probably gone away.  If this device isn't
 6099                  * already marked unconfigured, notify the peripheral
 6100                  * drivers that this device is no more.
 6101                  */
 6102                 if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
 6103                         /* Send the async notification. */
 6104                         xpt_async(AC_LOST_DEVICE, path, NULL);
 6105 
 6106                 xpt_release_ccb(done_ccb);
 6107                 break;
 6108         }
 6109         case PROBE_MODE_SENSE:
 6110         {
 6111                 struct ccb_scsiio *csio;
 6112                 struct scsi_mode_header_6 *mode_hdr;
 6113 
 6114                 csio = &done_ccb->csio;
 6115                 mode_hdr = (struct scsi_mode_header_6 *)csio->data_ptr;
 6116                 if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
 6117                         struct scsi_control_page *page;
 6118                         u_int8_t *offset;
 6119 
 6120                         offset = ((u_int8_t *)&mode_hdr[1])
 6121                             + mode_hdr->blk_desc_len;
 6122                         page = (struct scsi_control_page *)offset;
 6123                         path->device->queue_flags = page->queue_flags;
 6124                 } else if (cam_periph_error(done_ccb, 0,
 6125                                             SF_RETRY_UA|SF_NO_PRINT,
 6126                                             &softc->saved_ccb) == ERESTART) {
 6127                         return;
 6128                 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 6129                         /* Don't wedge the queue */
 6130                         xpt_release_devq(done_ccb->ccb_h.path,
 6131                                          /*count*/1, /*run_queue*/TRUE);
 6132                 }
 6133                 xpt_release_ccb(done_ccb);
 6134                 free(mode_hdr, M_CAMXPT);
 6135                 PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_0);
 6136                 xpt_schedule(periph, priority);
 6137                 return;
 6138         }
 6139         case PROBE_SERIAL_NUM_0:
 6140         {
 6141                 struct ccb_scsiio *csio;
 6142                 struct scsi_vpd_supported_page_list *page_list;
 6143                 int length, serialnum_supported, i;
 6144 
 6145                 serialnum_supported = 0;
 6146                 csio = &done_ccb->csio;
 6147                 page_list =
 6148                     (struct scsi_vpd_supported_page_list *)csio->data_ptr;
 6149 
 6150                 if (page_list == NULL) {
 6151                         /*
 6152                          * Don't process the command as it was never sent
 6153                          */
 6154                 } else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP
 6155                     && (page_list->length > 0)) {
 6156                         length = min(page_list->length,
 6157                             SVPD_SUPPORTED_PAGES_SIZE);
 6158                         for (i = 0; i < length; i++) {
 6159                                 if (page_list->list[i] ==
 6160                                     SVPD_UNIT_SERIAL_NUMBER) {
 6161                                         serialnum_supported = 1;
 6162                                         break;
 6163                                 }
 6164                         }
 6165                 } else if (cam_periph_error(done_ccb, 0,
 6166                                             SF_RETRY_UA|SF_NO_PRINT,
 6167                                             &softc->saved_ccb) == ERESTART) {
 6168                         return;
 6169                 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 6170                         /* Don't wedge the queue */
 6171                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 6172                                          /*run_queue*/TRUE);
 6173                 }
 6174 
 6175                 if (page_list != NULL)
 6176                         free(page_list, M_CAMXPT);
 6177 
 6178                 if (serialnum_supported) {
 6179                         xpt_release_ccb(done_ccb);
 6180                         PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM_1);
 6181                         xpt_schedule(periph, priority);
 6182                         return;
 6183                 }
 6184 
 6185                 csio->data_ptr = NULL;
 6186                 /* FALLTHROUGH */
 6187         }
 6188 
 6189         case PROBE_SERIAL_NUM_1:
 6190         {
 6191                 struct ccb_scsiio *csio;
 6192                 struct scsi_vpd_unit_serial_number *serial_buf;
 6193                 u_int32_t  priority;
 6194                 int changed;
 6195                 int have_serialnum;
 6196 
 6197                 changed = 1;
 6198                 have_serialnum = 0;
 6199                 csio = &done_ccb->csio;
 6200                 priority = done_ccb->ccb_h.pinfo.priority;
 6201                 serial_buf =
 6202                     (struct scsi_vpd_unit_serial_number *)csio->data_ptr;
 6203 
 6204                 /* Clean up from previous instance of this device */
 6205                 if (path->device->serial_num != NULL) {
 6206                         free(path->device->serial_num, M_CAMXPT);
 6207                         path->device->serial_num = NULL;
 6208                         path->device->serial_num_len = 0;
 6209                 }
 6210 
 6211                 if (serial_buf == NULL) {
 6212                         /*
 6213                          * Don't process the command as it was never sent
 6214                          */
 6215                 } else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP
 6216                         && (serial_buf->length > 0)) {
 6217 
 6218                         have_serialnum = 1;
 6219                         path->device->serial_num =
 6220                                 (u_int8_t *)malloc((serial_buf->length + 1),
 6221                                                    M_CAMXPT, M_NOWAIT);
 6222                         if (path->device->serial_num != NULL) {
 6223                                 bcopy(serial_buf->serial_num,
 6224                                       path->device->serial_num,
 6225                                       serial_buf->length);
 6226                                 path->device->serial_num_len =
 6227                                     serial_buf->length;
 6228                                 path->device->serial_num[serial_buf->length]
 6229                                     = '\0';
 6230                         }
 6231                 } else if (cam_periph_error(done_ccb, 0,
 6232                                             SF_RETRY_UA|SF_NO_PRINT,
 6233                                             &softc->saved_ccb) == ERESTART) {
 6234                         return;
 6235                 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 6236                         /* Don't wedge the queue */
 6237                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 6238                                          /*run_queue*/TRUE);
 6239                 }
 6240 
 6241                 /*
 6242                  * Let's see if we have seen this device before.
 6243                  */
 6244                 if ((softc->flags & PROBE_INQUIRY_CKSUM) != 0) {
 6245                         MD5_CTX context;
 6246                         u_int8_t digest[16];
 6247 
 6248                         MD5Init(&context);
 6249 
 6250                         MD5Update(&context,
 6251                                   (unsigned char *)&path->device->inq_data,
 6252                                   sizeof(struct scsi_inquiry_data));
 6253 
 6254                         if (have_serialnum)
 6255                                 MD5Update(&context, serial_buf->serial_num,
 6256                                           serial_buf->length);
 6257 
 6258                         MD5Final(digest, &context);
 6259                         if (bcmp(softc->digest, digest, 16) == 0)
 6260                                 changed = 0;
 6261 
 6262                         /*
 6263                          * XXX Do we need to do a TUR in order to ensure
 6264                          *     that the device really hasn't changed???
 6265                          */
 6266                         if ((changed != 0)
 6267                          && ((softc->flags & PROBE_NO_ANNOUNCE) == 0))
 6268                                 xpt_async(AC_LOST_DEVICE, path, NULL);
 6269                 }
 6270                 if (serial_buf != NULL)
 6271                         free(serial_buf, M_CAMXPT);
 6272 
 6273                 if (changed != 0) {
 6274                         /*
 6275                          * Now that we have all the necessary
 6276                          * information to safely perform transfer
 6277                          * negotiations... Controllers don't perform
 6278                          * any negotiation or tagged queuing until
 6279                          * after the first XPT_SET_TRAN_SETTINGS ccb is
 6280                          * received.  So, on a new device, just retrieve
 6281                          * the user settings, and set them as the current
 6282                          * settings to set the device up.
 6283                          */
 6284                         proberequestdefaultnegotiation(periph);
 6285                         xpt_release_ccb(done_ccb);
 6286 
 6287                         /*
 6288                          * Perform a TUR to allow the controller to
 6289                          * perform any necessary transfer negotiation.
 6290                          */
 6291                         PROBE_SET_ACTION(softc, PROBE_TUR_FOR_NEGOTIATION);
 6292                         xpt_schedule(periph, priority);
 6293                         return;
 6294                 }
 6295                 xpt_release_ccb(done_ccb);
 6296                 break;
 6297         }
 6298         case PROBE_TUR_FOR_NEGOTIATION:
 6299                 if ((done_ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 6300                         DELAY(500000);
 6301                         if (cam_periph_error(done_ccb, 0, SF_RETRY_UA,
 6302                             NULL) == ERESTART)
 6303                                 return;
 6304                 }
 6305         /* FALLTHROUGH */
 6306         case PROBE_DV_EXIT:
 6307                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 6308                         /* Don't wedge the queue */
 6309                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 6310                                          /*run_queue*/TRUE);
 6311                 }
 6312                 /*
 6313                  * Do Domain Validation for lun 0 on devices that claim
 6314                  * to support Synchronous Transfer modes.
 6315                  */
 6316                 if (softc->action == PROBE_TUR_FOR_NEGOTIATION
 6317                  && done_ccb->ccb_h.target_lun == 0
 6318                  && (path->device->inq_data.flags & SID_Sync) != 0
 6319                  && (path->device->flags & CAM_DEV_IN_DV) == 0) {
 6320                         CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
 6321                             ("Begin Domain Validation\n"));
 6322                         path->device->flags |= CAM_DEV_IN_DV;
 6323                         xpt_release_ccb(done_ccb);
 6324                         PROBE_SET_ACTION(softc, PROBE_INQUIRY_BASIC_DV1);
 6325                         xpt_schedule(periph, priority);
 6326                         return;
 6327                 }
 6328                 if (softc->action == PROBE_DV_EXIT) {
 6329                         CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
 6330                             ("Leave Domain Validation\n"));
 6331                 }
 6332                 path->device->flags &=
 6333                     ~(CAM_DEV_UNCONFIGURED|CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
 6334                 if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
 6335                         /* Inform the XPT that a new device has been found */
 6336                         done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 6337                         xpt_action(done_ccb);
 6338                         xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
 6339                                   done_ccb);
 6340                 }
 6341                 xpt_release_ccb(done_ccb);
 6342                 break;
 6343         case PROBE_INQUIRY_BASIC_DV1:
 6344         case PROBE_INQUIRY_BASIC_DV2:
 6345         {
 6346                 struct scsi_inquiry_data *nbuf;
 6347                 struct ccb_scsiio *csio;
 6348 
 6349                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 6350                         /* Don't wedge the queue */
 6351                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 6352                                          /*run_queue*/TRUE);
 6353                 }
 6354                 csio = &done_ccb->csio;
 6355                 nbuf = (struct scsi_inquiry_data *)csio->data_ptr;
 6356                 if (bcmp(nbuf, &path->device->inq_data, SHORT_INQUIRY_LENGTH)) {
 6357                         xpt_print(path,
 6358                             "inquiry data fails comparison at DV%d step\n",
 6359                             softc->action == PROBE_INQUIRY_BASIC_DV1 ? 1 : 2);
 6360                         if (proberequestbackoff(periph, path->device)) {
 6361                                 path->device->flags &= ~CAM_DEV_IN_DV;
 6362                                 PROBE_SET_ACTION(softc, PROBE_TUR_FOR_NEGOTIATION);
 6363                         } else {
 6364                                 /* give up */
 6365                                 PROBE_SET_ACTION(softc, PROBE_DV_EXIT);
 6366                         }
 6367                         free(nbuf, M_CAMXPT);
 6368                         xpt_release_ccb(done_ccb);
 6369                         xpt_schedule(periph, priority);
 6370                         return;
 6371                 }
 6372                 free(nbuf, M_CAMXPT);
 6373                 if (softc->action == PROBE_INQUIRY_BASIC_DV1) {
 6374                         PROBE_SET_ACTION(softc, PROBE_INQUIRY_BASIC_DV2);
 6375                         xpt_release_ccb(done_ccb);
 6376                         xpt_schedule(periph, priority);
 6377                         return;
 6378                 }
 6379                 if (softc->action == PROBE_INQUIRY_BASIC_DV2) {
 6380                         CAM_DEBUG(periph->path, CAM_DEBUG_INFO,
 6381                             ("Leave Domain Validation Successfully\n"));
 6382                 }
 6383                 path->device->flags &=
 6384                     ~(CAM_DEV_UNCONFIGURED|CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
 6385                 if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
 6386                         /* Inform the XPT that a new device has been found */
 6387                         done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 6388                         xpt_action(done_ccb);
 6389                         xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
 6390                                   done_ccb);
 6391                 }
 6392                 xpt_release_ccb(done_ccb);
 6393                 break;
 6394         }
 6395         case PROBE_INVALID:
 6396                 CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_INFO,
 6397                     ("probedone: invalid action state\n"));
 6398         default:
 6399                 break;
 6400         }
 6401         done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
 6402         TAILQ_REMOVE(&softc->request_ccbs, &done_ccb->ccb_h, periph_links.tqe);
 6403         done_ccb->ccb_h.status = CAM_REQ_CMP;
 6404         xpt_done(done_ccb);
 6405         if (TAILQ_FIRST(&softc->request_ccbs) == NULL) {
 6406                 cam_periph_invalidate(periph);
 6407                 cam_periph_release_locked(periph);
 6408         } else {
 6409                 probeschedule(periph);
 6410         }
 6411 }
 6412 
 6413 static void
 6414 probecleanup(struct cam_periph *periph)
 6415 {
 6416         free(periph->softc, M_CAMXPT);
 6417 }
 6418 
 6419 static void
 6420 xpt_find_quirk(struct cam_ed *device)
 6421 {
 6422         caddr_t match;
 6423 
 6424         match = cam_quirkmatch((caddr_t)&device->inq_data,
 6425                                (caddr_t)xpt_quirk_table,
 6426                                sizeof(xpt_quirk_table)/sizeof(*xpt_quirk_table),
 6427                                sizeof(*xpt_quirk_table), scsi_inquiry_match);
 6428 
 6429         if (match == NULL)
 6430                 panic("xpt_find_quirk: device didn't match wildcard entry!!");
 6431 
 6432         device->quirk = (struct xpt_quirk_entry *)match;
 6433 }
 6434 
 6435 static int
 6436 sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS)
 6437 {
 6438         int error, bool;
 6439 
 6440         bool = cam_srch_hi;
 6441         error = sysctl_handle_int(oidp, &bool, 0, req);
 6442         if (error != 0 || req->newptr == NULL)
 6443                 return (error);
 6444         if (bool == 0 || bool == 1) {
 6445                 cam_srch_hi = bool;
 6446                 return (0);
 6447         } else {
 6448                 return (EINVAL);
 6449         }
 6450 }
 6451 
 6452 
 6453 static void
 6454 xpt_devise_transport(struct cam_path *path)
 6455 {
 6456         struct ccb_pathinq cpi;
 6457         struct ccb_trans_settings cts;
 6458         struct scsi_inquiry_data *inq_buf;
 6459 
 6460         /* Get transport information from the SIM */
 6461         xpt_setup_ccb(&cpi.ccb_h, path, /*priority*/1);
 6462         cpi.ccb_h.func_code = XPT_PATH_INQ;
 6463         xpt_action((union ccb *)&cpi);
 6464 
 6465         inq_buf = NULL;
 6466         if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0)
 6467                 inq_buf = &path->device->inq_data;
 6468         path->device->protocol = PROTO_SCSI;
 6469         path->device->protocol_version =
 6470             inq_buf != NULL ? SID_ANSI_REV(inq_buf) : cpi.protocol_version;
 6471         path->device->transport = cpi.transport;
 6472         path->device->transport_version = cpi.transport_version;
 6473 
 6474         /*
 6475          * Any device not using SPI3 features should
 6476          * be considered SPI2 or lower.
 6477          */
 6478         if (inq_buf != NULL) {
 6479                 if (path->device->transport == XPORT_SPI
 6480                  && (inq_buf->spi3data & SID_SPI_MASK) == 0
 6481                  && path->device->transport_version > 2)
 6482                         path->device->transport_version = 2;
 6483         } else {
 6484                 struct cam_ed* otherdev;
 6485 
 6486                 for (otherdev = TAILQ_FIRST(&path->target->ed_entries);
 6487                      otherdev != NULL;
 6488                      otherdev = TAILQ_NEXT(otherdev, links)) {
 6489                         if (otherdev != path->device)
 6490                                 break;
 6491                 }
 6492 
 6493                 if (otherdev != NULL) {
 6494                         /*
 6495                          * Initially assume the same versioning as
 6496                          * prior luns for this target.
 6497                          */
 6498                         path->device->protocol_version =
 6499                             otherdev->protocol_version;
 6500                         path->device->transport_version =
 6501                             otherdev->transport_version;
 6502                 } else {
 6503                         /* Until we know better, opt for safty */
 6504                         path->device->protocol_version = 2;
 6505                         if (path->device->transport == XPORT_SPI)
 6506                                 path->device->transport_version = 2;
 6507                         else
 6508                                 path->device->transport_version = 0;
 6509                 }
 6510         }
 6511 
 6512         /*
 6513          * XXX
 6514          * For a device compliant with SPC-2 we should be able
 6515          * to determine the transport version supported by
 6516          * scrutinizing the version descriptors in the
 6517          * inquiry buffer.
 6518          */
 6519 
 6520         /* Tell the controller what we think */
 6521         xpt_setup_ccb(&cts.ccb_h, path, /*priority*/1);
 6522         cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
 6523         cts.type = CTS_TYPE_CURRENT_SETTINGS;
 6524         cts.transport = path->device->transport;
 6525         cts.transport_version = path->device->transport_version;
 6526         cts.protocol = path->device->protocol;
 6527         cts.protocol_version = path->device->protocol_version;
 6528         cts.proto_specific.valid = 0;
 6529         cts.xport_specific.valid = 0;
 6530         xpt_action((union ccb *)&cts);
 6531 }
 6532 
 6533 static void
 6534 xpt_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_ed *device,
 6535                           int async_update)
 6536 {
 6537         struct  ccb_pathinq cpi;
 6538         struct  ccb_trans_settings cur_cts;
 6539         struct  ccb_trans_settings_scsi *scsi;
 6540         struct  ccb_trans_settings_scsi *cur_scsi;
 6541         struct  cam_sim *sim;
 6542         struct  scsi_inquiry_data *inq_data;
 6543 
 6544         if (device == NULL) {
 6545                 cts->ccb_h.status = CAM_PATH_INVALID;
 6546                 xpt_done((union ccb *)cts);
 6547                 return;
 6548         }
 6549 
 6550         if (cts->protocol == PROTO_UNKNOWN
 6551          || cts->protocol == PROTO_UNSPECIFIED) {
 6552                 cts->protocol = device->protocol;
 6553                 cts->protocol_version = device->protocol_version;
 6554         }
 6555 
 6556         if (cts->protocol_version == PROTO_VERSION_UNKNOWN
 6557          || cts->protocol_version == PROTO_VERSION_UNSPECIFIED)
 6558                 cts->protocol_version = device->protocol_version;
 6559 
 6560         if (cts->protocol != device->protocol) {
 6561                 xpt_print(cts->ccb_h.path, "Uninitialized Protocol %x:%x?\n",
 6562                        cts->protocol, device->protocol);
 6563                 cts->protocol = device->protocol;
 6564         }
 6565 
 6566         if (cts->protocol_version > device->protocol_version) {
 6567                 if (bootverbose) {
 6568                         xpt_print(cts->ccb_h.path, "Down reving Protocol "
 6569                             "Version from %d to %d?\n", cts->protocol_version,
 6570                             device->protocol_version);
 6571                 }
 6572                 cts->protocol_version = device->protocol_version;
 6573         }
 6574 
 6575         if (cts->transport == XPORT_UNKNOWN
 6576          || cts->transport == XPORT_UNSPECIFIED) {
 6577                 cts->transport = device->transport;
 6578                 cts->transport_version = device->transport_version;
 6579         }
 6580 
 6581         if (cts->transport_version == XPORT_VERSION_UNKNOWN
 6582          || cts->transport_version == XPORT_VERSION_UNSPECIFIED)
 6583                 cts->transport_version = device->transport_version;
 6584 
 6585         if (cts->transport != device->transport) {
 6586                 xpt_print(cts->ccb_h.path, "Uninitialized Transport %x:%x?\n",
 6587                     cts->transport, device->transport);
 6588                 cts->transport = device->transport;
 6589         }
 6590 
 6591         if (cts->transport_version > device->transport_version) {
 6592                 if (bootverbose) {
 6593                         xpt_print(cts->ccb_h.path, "Down reving Transport "
 6594                             "Version from %d to %d?\n", cts->transport_version,
 6595                             device->transport_version);
 6596                 }
 6597                 cts->transport_version = device->transport_version;
 6598         }
 6599 
 6600         sim = cts->ccb_h.path->bus->sim;
 6601 
 6602         /*
 6603          * Nothing more of interest to do unless
 6604          * this is a device connected via the
 6605          * SCSI protocol.
 6606          */
 6607         if (cts->protocol != PROTO_SCSI) {
 6608                 if (async_update == FALSE)
 6609                         (*(sim->sim_action))(sim, (union ccb *)cts);
 6610                 return;
 6611         }
 6612 
 6613         inq_data = &device->inq_data;
 6614         scsi = &cts->proto_specific.scsi;
 6615         xpt_setup_ccb(&cpi.ccb_h, cts->ccb_h.path, /*priority*/1);
 6616         cpi.ccb_h.func_code = XPT_PATH_INQ;
 6617         xpt_action((union ccb *)&cpi);
 6618 
 6619         /* SCSI specific sanity checking */
 6620         if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0
 6621          || (INQ_DATA_TQ_ENABLED(inq_data)) == 0
 6622          || (device->queue_flags & SCP_QUEUE_DQUE) != 0
 6623          || (device->quirk->mintags == 0)) {
 6624                 /*
 6625                  * Can't tag on hardware that doesn't support tags,
 6626                  * doesn't have it enabled, or has broken tag support.
 6627                  */
 6628                 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 6629         }
 6630 
 6631         if (async_update == FALSE) {
 6632                 /*
 6633                  * Perform sanity checking against what the
 6634                  * controller and device can do.
 6635                  */
 6636                 xpt_setup_ccb(&cur_cts.ccb_h, cts->ccb_h.path, /*priority*/1);
 6637                 cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 6638                 cur_cts.type = cts->type;
 6639                 xpt_action((union ccb *)&cur_cts);
 6640                 if ((cur_cts.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 6641                         return;
 6642                 }
 6643                 cur_scsi = &cur_cts.proto_specific.scsi;
 6644                 if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) {
 6645                         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 6646                         scsi->flags |= cur_scsi->flags & CTS_SCSI_FLAGS_TAG_ENB;
 6647                 }
 6648                 if ((cur_scsi->valid & CTS_SCSI_VALID_TQ) == 0)
 6649                         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 6650         }
 6651 
 6652         /* SPI specific sanity checking */
 6653         if (cts->transport == XPORT_SPI && async_update == FALSE) {
 6654                 u_int spi3caps;
 6655                 struct ccb_trans_settings_spi *spi;
 6656                 struct ccb_trans_settings_spi *cur_spi;
 6657 
 6658                 spi = &cts->xport_specific.spi;
 6659 
 6660                 cur_spi = &cur_cts.xport_specific.spi;
 6661 
 6662                 /* Fill in any gaps in what the user gave us */
 6663                 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0)
 6664                         spi->sync_period = cur_spi->sync_period;
 6665                 if ((cur_spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0)
 6666                         spi->sync_period = 0;
 6667                 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0)
 6668                         spi->sync_offset = cur_spi->sync_offset;
 6669                 if ((cur_spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0)
 6670                         spi->sync_offset = 0;
 6671                 if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0)
 6672                         spi->ppr_options = cur_spi->ppr_options;
 6673                 if ((cur_spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0)
 6674                         spi->ppr_options = 0;
 6675                 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) == 0)
 6676                         spi->bus_width = cur_spi->bus_width;
 6677                 if ((cur_spi->valid & CTS_SPI_VALID_BUS_WIDTH) == 0)
 6678                         spi->bus_width = 0;
 6679                 if ((spi->valid & CTS_SPI_VALID_DISC) == 0) {
 6680                         spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
 6681                         spi->flags |= cur_spi->flags & CTS_SPI_FLAGS_DISC_ENB;
 6682                 }
 6683                 if ((cur_spi->valid & CTS_SPI_VALID_DISC) == 0)
 6684                         spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
 6685                 if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0
 6686                   && (inq_data->flags & SID_Sync) == 0
 6687                   && cts->type == CTS_TYPE_CURRENT_SETTINGS)
 6688                  || ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0)) {
 6689                         /* Force async */
 6690                         spi->sync_period = 0;
 6691                         spi->sync_offset = 0;
 6692                 }
 6693 
 6694                 switch (spi->bus_width) {
 6695                 case MSG_EXT_WDTR_BUS_32_BIT:
 6696                         if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0
 6697                           || (inq_data->flags & SID_WBus32) != 0
 6698                           || cts->type == CTS_TYPE_USER_SETTINGS)
 6699                          && (cpi.hba_inquiry & PI_WIDE_32) != 0)
 6700                                 break;
 6701                         /* Fall Through to 16-bit */
 6702                 case MSG_EXT_WDTR_BUS_16_BIT:
 6703                         if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0
 6704                           || (inq_data->flags & SID_WBus16) != 0
 6705                           || cts->type == CTS_TYPE_USER_SETTINGS)
 6706                          && (cpi.hba_inquiry & PI_WIDE_16) != 0) {
 6707                                 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 6708                                 break;
 6709                         }
 6710                         /* Fall Through to 8-bit */
 6711                 default: /* New bus width?? */
 6712                 case MSG_EXT_WDTR_BUS_8_BIT:
 6713                         /* All targets can do this */
 6714                         spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
 6715                         break;
 6716                 }
 6717 
 6718                 spi3caps = cpi.xport_specific.spi.ppr_options;
 6719                 if ((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0
 6720                  && cts->type == CTS_TYPE_CURRENT_SETTINGS)
 6721                         spi3caps &= inq_data->spi3data;
 6722 
 6723                 if ((spi3caps & SID_SPI_CLOCK_DT) == 0)
 6724                         spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ;
 6725 
 6726                 if ((spi3caps & SID_SPI_IUS) == 0)
 6727                         spi->ppr_options &= ~MSG_EXT_PPR_IU_REQ;
 6728 
 6729                 if ((spi3caps & SID_SPI_QAS) == 0)
 6730                         spi->ppr_options &= ~MSG_EXT_PPR_QAS_REQ;
 6731 
 6732                 /* No SPI Transfer settings are allowed unless we are wide */
 6733                 if (spi->bus_width == 0)
 6734                         spi->ppr_options = 0;
 6735 
 6736                 if ((spi->valid & CTS_SPI_VALID_DISC)
 6737                  && ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) == 0)) {
 6738                         /*
 6739                          * Can't tag queue without disconnection.
 6740                          */
 6741                         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 6742                         scsi->valid |= CTS_SCSI_VALID_TQ;
 6743                 }
 6744 
 6745                 /*
 6746                  * If we are currently performing tagged transactions to
 6747                  * this device and want to change its negotiation parameters,
 6748                  * go non-tagged for a bit to give the controller a chance to
 6749                  * negotiate unhampered by tag messages.
 6750                  */
 6751                 if (cts->type == CTS_TYPE_CURRENT_SETTINGS
 6752                  && (device->inq_flags & SID_CmdQue) != 0
 6753                  && (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0
 6754                  && (spi->flags & (CTS_SPI_VALID_SYNC_RATE|
 6755                                    CTS_SPI_VALID_SYNC_OFFSET|
 6756                                    CTS_SPI_VALID_BUS_WIDTH)) != 0)
 6757                         xpt_toggle_tags(cts->ccb_h.path);
 6758         }
 6759 
 6760         if (cts->type == CTS_TYPE_CURRENT_SETTINGS
 6761          && (scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
 6762                 int device_tagenb;
 6763 
 6764                 /*
 6765                  * If we are transitioning from tags to no-tags or
 6766                  * vice-versa, we need to carefully freeze and restart
 6767                  * the queue so that we don't overlap tagged and non-tagged
 6768                  * commands.  We also temporarily stop tags if there is
 6769                  * a change in transfer negotiation settings to allow
 6770                  * "tag-less" negotiation.
 6771                  */
 6772                 if ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
 6773                  || (device->inq_flags & SID_CmdQue) != 0)
 6774                         device_tagenb = TRUE;
 6775                 else
 6776                         device_tagenb = FALSE;
 6777 
 6778                 if (((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0
 6779                   && device_tagenb == FALSE)
 6780                  || ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) == 0
 6781                   && device_tagenb == TRUE)) {
 6782 
 6783                         if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
 6784                                 /*
 6785                                  * Delay change to use tags until after a
 6786                                  * few commands have gone to this device so
 6787                                  * the controller has time to perform transfer
 6788                                  * negotiations without tagged messages getting
 6789                                  * in the way.
 6790                                  */
 6791                                 device->tag_delay_count = CAM_TAG_DELAY_COUNT;
 6792                                 device->flags |= CAM_DEV_TAG_AFTER_COUNT;
 6793                         } else {
 6794                                 struct ccb_relsim crs;
 6795 
 6796                                 xpt_freeze_devq(cts->ccb_h.path, /*count*/1);
 6797                                 device->inq_flags &= ~SID_CmdQue;
 6798                                 xpt_dev_ccbq_resize(cts->ccb_h.path,
 6799                                                     sim->max_dev_openings);
 6800                                 device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
 6801                                 device->tag_delay_count = 0;
 6802 
 6803                                 xpt_setup_ccb(&crs.ccb_h, cts->ccb_h.path,
 6804                                               /*priority*/1);
 6805                                 crs.ccb_h.func_code = XPT_REL_SIMQ;
 6806                                 crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
 6807                                 crs.openings
 6808                                     = crs.release_timeout
 6809                                     = crs.qfrozen_cnt
 6810                                     = 0;
 6811                                 xpt_action((union ccb *)&crs);
 6812                         }
 6813                 }
 6814         }
 6815         if (async_update == FALSE)
 6816                 (*(sim->sim_action))(sim, (union ccb *)cts);
 6817 }
 6818 
 6819 
 6820 static void
 6821 xpt_toggle_tags(struct cam_path *path)
 6822 {
 6823         struct cam_ed *dev;
 6824 
 6825         /*
 6826          * Give controllers a chance to renegotiate
 6827          * before starting tag operations.  We
 6828          * "toggle" tagged queuing off then on
 6829          * which causes the tag enable command delay
 6830          * counter to come into effect.
 6831          */
 6832         dev = path->device;
 6833         if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
 6834          || ((dev->inq_flags & SID_CmdQue) != 0
 6835           && (dev->inq_flags & (SID_Sync|SID_WBus16|SID_WBus32)) != 0)) {
 6836                 struct ccb_trans_settings cts;
 6837 
 6838                 xpt_setup_ccb(&cts.ccb_h, path, 1);
 6839                 cts.protocol = PROTO_SCSI;
 6840                 cts.protocol_version = PROTO_VERSION_UNSPECIFIED;
 6841                 cts.transport = XPORT_UNSPECIFIED;
 6842                 cts.transport_version = XPORT_VERSION_UNSPECIFIED;
 6843                 cts.proto_specific.scsi.flags = 0;
 6844                 cts.proto_specific.scsi.valid = CTS_SCSI_VALID_TQ;
 6845                 xpt_set_transfer_settings(&cts, path->device,
 6846                                           /*async_update*/TRUE);
 6847                 cts.proto_specific.scsi.flags = CTS_SCSI_FLAGS_TAG_ENB;
 6848                 xpt_set_transfer_settings(&cts, path->device,
 6849                                           /*async_update*/TRUE);
 6850         }
 6851 }
 6852 
 6853 static void
 6854 xpt_start_tags(struct cam_path *path)
 6855 {
 6856         struct ccb_relsim crs;
 6857         struct cam_ed *device;
 6858         struct cam_sim *sim;
 6859         int    newopenings;
 6860 
 6861         device = path->device;
 6862         sim = path->bus->sim;
 6863         device->flags &= ~CAM_DEV_TAG_AFTER_COUNT;
 6864         xpt_freeze_devq(path, /*count*/1);
 6865         device->inq_flags |= SID_CmdQue;
 6866         if (device->tag_saved_openings != 0)
 6867                 newopenings = device->tag_saved_openings;
 6868         else
 6869                 newopenings = min(device->quirk->maxtags,
 6870                                   sim->max_tagged_dev_openings);
 6871         xpt_dev_ccbq_resize(path, newopenings);
 6872         xpt_setup_ccb(&crs.ccb_h, path, /*priority*/1);
 6873         crs.ccb_h.func_code = XPT_REL_SIMQ;
 6874         crs.release_flags = RELSIM_RELEASE_AFTER_QEMPTY;
 6875         crs.openings
 6876             = crs.release_timeout
 6877             = crs.qfrozen_cnt
 6878             = 0;
 6879         xpt_action((union ccb *)&crs);
 6880 }
 6881 
 6882 static int busses_to_config;
 6883 static int busses_to_reset;
 6884 
 6885 static int
 6886 xptconfigbuscountfunc(struct cam_eb *bus, void *arg)
 6887 {
 6888 
 6889         mtx_assert(bus->sim->mtx, MA_OWNED);
 6890 
 6891         if (bus->path_id != CAM_XPT_PATH_ID) {
 6892                 struct cam_path path;
 6893                 struct ccb_pathinq cpi;
 6894                 int can_negotiate;
 6895 
 6896                 busses_to_config++;
 6897                 xpt_compile_path(&path, NULL, bus->path_id,
 6898                                  CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
 6899                 xpt_setup_ccb(&cpi.ccb_h, &path, /*priority*/1);
 6900                 cpi.ccb_h.func_code = XPT_PATH_INQ;
 6901                 xpt_action((union ccb *)&cpi);
 6902                 can_negotiate = cpi.hba_inquiry;
 6903                 can_negotiate &= (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE);
 6904                 if ((cpi.hba_misc & PIM_NOBUSRESET) == 0
 6905                  && can_negotiate)
 6906                         busses_to_reset++;
 6907                 xpt_release_path(&path);
 6908         }
 6909 
 6910         return(1);
 6911 }
 6912 
 6913 static int
 6914 xptconfigfunc(struct cam_eb *bus, void *arg)
 6915 {
 6916         struct  cam_path *path;
 6917         union   ccb *work_ccb;
 6918 
 6919         mtx_assert(bus->sim->mtx, MA_OWNED);
 6920 
 6921         if (bus->path_id != CAM_XPT_PATH_ID) {
 6922                 cam_status status;
 6923                 int can_negotiate;
 6924 
 6925                 work_ccb = xpt_alloc_ccb_nowait();
 6926                 if (work_ccb == NULL) {
 6927                         busses_to_config--;
 6928                         xpt_finishconfig(xpt_periph, NULL);
 6929                         return(0);
 6930                 }
 6931                 if ((status = xpt_create_path(&path, xpt_periph, bus->path_id,
 6932                                               CAM_TARGET_WILDCARD,
 6933                                               CAM_LUN_WILDCARD)) !=CAM_REQ_CMP){
 6934                         printf("xptconfigfunc: xpt_create_path failed with "
 6935                                "status %#x for bus %d\n", status, bus->path_id);
 6936                         printf("xptconfigfunc: halting bus configuration\n");
 6937                         xpt_free_ccb(work_ccb);
 6938                         busses_to_config--;
 6939                         xpt_finishconfig(xpt_periph, NULL);
 6940                         return(0);
 6941                 }
 6942                 xpt_setup_ccb(&work_ccb->ccb_h, path, /*priority*/1);
 6943                 work_ccb->ccb_h.func_code = XPT_PATH_INQ;
 6944                 xpt_action(work_ccb);
 6945                 if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
 6946                         printf("xptconfigfunc: CPI failed on bus %d "
 6947                                "with status %d\n", bus->path_id,
 6948                                work_ccb->ccb_h.status);
 6949                         xpt_finishconfig(xpt_periph, work_ccb);
 6950                         return(1);
 6951                 }
 6952 
 6953                 can_negotiate = work_ccb->cpi.hba_inquiry;
 6954                 can_negotiate &= (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE);
 6955                 if ((work_ccb->cpi.hba_misc & PIM_NOBUSRESET) == 0
 6956                  && (can_negotiate != 0)) {
 6957                         xpt_setup_ccb(&work_ccb->ccb_h, path, /*priority*/1);
 6958                         work_ccb->ccb_h.func_code = XPT_RESET_BUS;
 6959                         work_ccb->ccb_h.cbfcnp = NULL;
 6960                         CAM_DEBUG(path, CAM_DEBUG_SUBTRACE,
 6961                                   ("Resetting Bus\n"));
 6962                         xpt_action(work_ccb);
 6963                         xpt_finishconfig(xpt_periph, work_ccb);
 6964                 } else {
 6965                         /* Act as though we performed a successful BUS RESET */
 6966                         work_ccb->ccb_h.func_code = XPT_RESET_BUS;
 6967                         xpt_finishconfig(xpt_periph, work_ccb);
 6968                 }
 6969         }
 6970 
 6971         return(1);
 6972 }
 6973 
 6974 static void
 6975 xpt_config(void *arg)
 6976 {
 6977         /*
 6978          * Now that interrupts are enabled, go find our devices
 6979          */
 6980 
 6981 #ifdef CAMDEBUG
 6982         /* Setup debugging flags and path */
 6983 #ifdef CAM_DEBUG_FLAGS
 6984         cam_dflags = CAM_DEBUG_FLAGS;
 6985 #else /* !CAM_DEBUG_FLAGS */
 6986         cam_dflags = CAM_DEBUG_NONE;
 6987 #endif /* CAM_DEBUG_FLAGS */
 6988 #ifdef CAM_DEBUG_BUS
 6989         if (cam_dflags != CAM_DEBUG_NONE) {
 6990                 /*
 6991                  * Locking is specifically omitted here.  No SIMs have
 6992                  * registered yet, so xpt_create_path will only be searching
 6993                  * empty lists of targets and devices.
 6994                  */
 6995                 if (xpt_create_path(&cam_dpath, xpt_periph,
 6996                                     CAM_DEBUG_BUS, CAM_DEBUG_TARGET,
 6997                                     CAM_DEBUG_LUN) != CAM_REQ_CMP) {
 6998                         printf("xpt_config: xpt_create_path() failed for debug"
 6999                                " target %d:%d:%d, debugging disabled\n",
 7000                                CAM_DEBUG_BUS, CAM_DEBUG_TARGET, CAM_DEBUG_LUN);
 7001                         cam_dflags = CAM_DEBUG_NONE;
 7002                 }
 7003         } else
 7004                 cam_dpath = NULL;
 7005 #else /* !CAM_DEBUG_BUS */
 7006         cam_dpath = NULL;
 7007 #endif /* CAM_DEBUG_BUS */
 7008 #endif /* CAMDEBUG */
 7009 
 7010         /*
 7011          * Scan all installed busses.
 7012          */
 7013         xpt_for_all_busses(xptconfigbuscountfunc, NULL);
 7014 
 7015         if (busses_to_config == 0) {
 7016                 /* Call manually because we don't have any busses */
 7017                 xpt_finishconfig(xpt_periph, NULL);
 7018         } else  {
 7019                 if (busses_to_reset > 0 && scsi_delay >= 2000) {
 7020                         printf("Waiting %d seconds for SCSI "
 7021                                "devices to settle\n", scsi_delay/1000);
 7022                 }
 7023                 xpt_for_all_busses(xptconfigfunc, NULL);
 7024         }
 7025 }
 7026 
 7027 /*
 7028  * If the given device only has one peripheral attached to it, and if that
 7029  * peripheral is the passthrough driver, announce it.  This insures that the
 7030  * user sees some sort of announcement for every peripheral in their system.
 7031  */
 7032 static int
 7033 xptpassannouncefunc(struct cam_ed *device, void *arg)
 7034 {
 7035         struct cam_periph *periph;
 7036         int i;
 7037 
 7038         for (periph = SLIST_FIRST(&device->periphs), i = 0; periph != NULL;
 7039              periph = SLIST_NEXT(periph, periph_links), i++);
 7040 
 7041         periph = SLIST_FIRST(&device->periphs);
 7042         if ((i == 1)
 7043          && (strncmp(periph->periph_name, "pass", 4) == 0))
 7044                 xpt_announce_periph(periph, NULL);
 7045 
 7046         return(1);
 7047 }
 7048 
 7049 static void
 7050 xpt_finishconfig_task(void *context, int pending)
 7051 {
 7052         struct  periph_driver **p_drv;
 7053         int     i;
 7054 
 7055         if (busses_to_config == 0) {
 7056                 /* Register all the peripheral drivers */
 7057                 /* XXX This will have to change when we have loadable modules */
 7058                 p_drv = periph_drivers;
 7059                 for (i = 0; p_drv[i] != NULL; i++) {
 7060                         (*p_drv[i]->init)();
 7061                 }
 7062 
 7063                 /*
 7064                  * Check for devices with no "standard" peripheral driver
 7065                  * attached.  For any devices like that, announce the
 7066                  * passthrough driver so the user will see something.
 7067                  */
 7068                 xpt_for_all_devices(xptpassannouncefunc, NULL);
 7069 
 7070                 /* Release our hook so that the boot can continue. */
 7071                 config_intrhook_disestablish(xsoftc.xpt_config_hook);
 7072                 free(xsoftc.xpt_config_hook, M_CAMXPT);
 7073                 xsoftc.xpt_config_hook = NULL;
 7074         }
 7075 
 7076         free(context, M_CAMXPT);
 7077 }
 7078 
 7079 static void
 7080 xpt_finishconfig(struct cam_periph *periph, union ccb *done_ccb)
 7081 {
 7082         struct  xpt_task *task;
 7083 
 7084         if (done_ccb != NULL) {
 7085                 CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE,
 7086                           ("xpt_finishconfig\n"));
 7087                 switch(done_ccb->ccb_h.func_code) {
 7088                 case XPT_RESET_BUS:
 7089                         if (done_ccb->ccb_h.status == CAM_REQ_CMP) {
 7090                                 done_ccb->ccb_h.func_code = XPT_SCAN_BUS;
 7091                                 done_ccb->ccb_h.cbfcnp = xpt_finishconfig;
 7092                                 done_ccb->crcn.flags = 0;
 7093                                 xpt_action(done_ccb);
 7094                                 return;
 7095                         }
 7096                         /* FALLTHROUGH */
 7097                 case XPT_SCAN_BUS:
 7098                 default:
 7099                         xpt_free_path(done_ccb->ccb_h.path);
 7100                         busses_to_config--;
 7101                         break;
 7102                 }
 7103         }
 7104 
 7105         if (busses_to_config == 0) {
 7106                 task = malloc(sizeof(struct xpt_task), M_CAMXPT, M_NOWAIT);
 7107                 if (task != NULL) {
 7108                         TASK_INIT(&task->task, 0, xpt_finishconfig_task, task);
 7109                         taskqueue_enqueue(taskqueue_thread, &task->task);
 7110                 }
 7111         }
 7112 
 7113         if (done_ccb != NULL)
 7114                 xpt_free_ccb(done_ccb);
 7115 }
 7116 
 7117 cam_status
 7118 xpt_register_async(int event, ac_callback_t *cbfunc, void *cbarg,
 7119                    struct cam_path *path)
 7120 {
 7121         struct ccb_setasync csa;
 7122         cam_status status;
 7123         int xptpath = 0;
 7124 
 7125         if (path == NULL) {
 7126                 mtx_lock(&xsoftc.xpt_lock);
 7127                 status = xpt_create_path(&path, /*periph*/NULL, CAM_XPT_PATH_ID,
 7128                                          CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD);
 7129                 if (status != CAM_REQ_CMP) {
 7130                         mtx_unlock(&xsoftc.xpt_lock);
 7131                         return (status);
 7132                 }
 7133                 xptpath = 1;
 7134         }
 7135 
 7136         xpt_setup_ccb(&csa.ccb_h, path, /*priority*/5);
 7137         csa.ccb_h.func_code = XPT_SASYNC_CB;
 7138         csa.event_enable = event;
 7139         csa.callback = cbfunc;
 7140         csa.callback_arg = cbarg;
 7141         xpt_action((union ccb *)&csa);
 7142         status = csa.ccb_h.status;
 7143         if (xptpath) {
 7144                 xpt_free_path(path);
 7145                 mtx_unlock(&xsoftc.xpt_lock);
 7146         }
 7147         return (status);
 7148 }
 7149 
 7150 static void
 7151 xptaction(struct cam_sim *sim, union ccb *work_ccb)
 7152 {
 7153         CAM_DEBUG(work_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("xptaction\n"));
 7154 
 7155         switch (work_ccb->ccb_h.func_code) {
 7156         /* Common cases first */
 7157         case XPT_PATH_INQ:              /* Path routing inquiry */
 7158         {
 7159                 struct ccb_pathinq *cpi;
 7160 
 7161                 cpi = &work_ccb->cpi;
 7162                 cpi->version_num = 1; /* XXX??? */
 7163                 cpi->hba_inquiry = 0;
 7164                 cpi->target_sprt = 0;
 7165                 cpi->hba_misc = 0;
 7166                 cpi->hba_eng_cnt = 0;
 7167                 cpi->max_target = 0;
 7168                 cpi->max_lun = 0;
 7169                 cpi->initiator_id = 0;
 7170                 strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
 7171                 strncpy(cpi->hba_vid, "", HBA_IDLEN);
 7172                 strncpy(cpi->dev_name, sim->sim_name, DEV_IDLEN);
 7173                 cpi->unit_number = sim->unit_number;
 7174                 cpi->bus_id = sim->bus_id;
 7175                 cpi->base_transfer_speed = 0;
 7176                 cpi->protocol = PROTO_UNSPECIFIED;
 7177                 cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
 7178                 cpi->transport = XPORT_UNSPECIFIED;
 7179                 cpi->transport_version = XPORT_VERSION_UNSPECIFIED;
 7180                 cpi->ccb_h.status = CAM_REQ_CMP;
 7181                 xpt_done(work_ccb);
 7182                 break;
 7183         }
 7184         default:
 7185                 work_ccb->ccb_h.status = CAM_REQ_INVALID;
 7186                 xpt_done(work_ccb);
 7187                 break;
 7188         }
 7189 }
 7190 
 7191 /*
 7192  * The xpt as a "controller" has no interrupt sources, so polling
 7193  * is a no-op.
 7194  */
 7195 static void
 7196 xptpoll(struct cam_sim *sim)
 7197 {
 7198 }
 7199 
 7200 void
 7201 xpt_lock_buses(void)
 7202 {
 7203         mtx_lock(&xsoftc.xpt_topo_lock);
 7204 }
 7205 
 7206 void
 7207 xpt_unlock_buses(void)
 7208 {
 7209         mtx_unlock(&xsoftc.xpt_topo_lock);
 7210 }
 7211 
 7212 static void
 7213 camisr(void *dummy)
 7214 {
 7215         cam_simq_t queue;
 7216         struct cam_sim *sim;
 7217 
 7218         mtx_lock(&cam_simq_lock);
 7219         TAILQ_INIT(&queue);
 7220         TAILQ_CONCAT(&queue, &cam_simq, links);
 7221         mtx_unlock(&cam_simq_lock);
 7222 
 7223         while ((sim = TAILQ_FIRST(&queue)) != NULL) {
 7224                 TAILQ_REMOVE(&queue, sim, links);
 7225                 CAM_SIM_LOCK(sim);
 7226                 sim->flags &= ~CAM_SIM_ON_DONEQ;
 7227                 camisr_runqueue(&sim->sim_doneq);
 7228                 CAM_SIM_UNLOCK(sim);
 7229         }
 7230 }
 7231 
 7232 static void
 7233 camisr_runqueue(void *V_queue)
 7234 {
 7235         cam_isrq_t *queue = V_queue;
 7236         struct  ccb_hdr *ccb_h;
 7237 
 7238         while ((ccb_h = TAILQ_FIRST(queue)) != NULL) {
 7239                 int     runq;
 7240 
 7241                 TAILQ_REMOVE(queue, ccb_h, sim_links.tqe);
 7242                 ccb_h->pinfo.index = CAM_UNQUEUED_INDEX;
 7243 
 7244                 CAM_DEBUG(ccb_h->path, CAM_DEBUG_TRACE,
 7245                           ("camisr\n"));
 7246 
 7247                 runq = FALSE;
 7248 
 7249                 if (ccb_h->flags & CAM_HIGH_POWER) {
 7250                         struct highpowerlist    *hphead;
 7251                         union ccb               *send_ccb;
 7252 
 7253                         mtx_lock(&xsoftc.xpt_lock);
 7254                         hphead = &xsoftc.highpowerq;
 7255 
 7256                         send_ccb = (union ccb *)STAILQ_FIRST(hphead);
 7257 
 7258                         /*
 7259                          * Increment the count since this command is done.
 7260                          */
 7261                         xsoftc.num_highpower++;
 7262 
 7263                         /*
 7264                          * Any high powered commands queued up?
 7265                          */
 7266                         if (send_ccb != NULL) {
 7267 
 7268                                 STAILQ_REMOVE_HEAD(hphead, xpt_links.stqe);
 7269                                 mtx_unlock(&xsoftc.xpt_lock);
 7270 
 7271                                 xpt_release_devq(send_ccb->ccb_h.path,
 7272                                                  /*count*/1, /*runqueue*/TRUE);
 7273                         } else
 7274                                 mtx_unlock(&xsoftc.xpt_lock);
 7275                 }
 7276 
 7277                 if ((ccb_h->func_code & XPT_FC_USER_CCB) == 0) {
 7278                         struct cam_ed *dev;
 7279 
 7280                         dev = ccb_h->path->device;
 7281 
 7282                         cam_ccbq_ccb_done(&dev->ccbq, (union ccb *)ccb_h);
 7283                         ccb_h->path->bus->sim->devq->send_active--;
 7284                         ccb_h->path->bus->sim->devq->send_openings++;
 7285 
 7286                         if (((dev->flags & CAM_DEV_REL_ON_COMPLETE) != 0
 7287                           && (ccb_h->status&CAM_STATUS_MASK) != CAM_REQUEUE_REQ)
 7288                          || ((dev->flags & CAM_DEV_REL_ON_QUEUE_EMPTY) != 0
 7289                           && (dev->ccbq.dev_active == 0))) {
 7290 
 7291                                 xpt_release_devq(ccb_h->path, /*count*/1,
 7292                                                  /*run_queue*/TRUE);
 7293                         }
 7294 
 7295                         if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
 7296                          && (--dev->tag_delay_count == 0))
 7297                                 xpt_start_tags(ccb_h->path);
 7298 
 7299                         if ((dev->ccbq.queue.entries > 0)
 7300                          && (dev->qfrozen_cnt == 0)
 7301                          && (device_is_send_queued(dev) == 0)) {
 7302                                 runq = xpt_schedule_dev_sendq(ccb_h->path->bus,
 7303                                                               dev);
 7304                         }
 7305                 }
 7306 
 7307                 if (ccb_h->status & CAM_RELEASE_SIMQ) {
 7308                         xpt_release_simq(ccb_h->path->bus->sim,
 7309                                          /*run_queue*/TRUE);
 7310                         ccb_h->status &= ~CAM_RELEASE_SIMQ;
 7311                         runq = FALSE;
 7312                 }
 7313 
 7314                 if ((ccb_h->flags & CAM_DEV_QFRZDIS)
 7315                  && (ccb_h->status & CAM_DEV_QFRZN)) {
 7316                         xpt_release_devq(ccb_h->path, /*count*/1,
 7317                                          /*run_queue*/TRUE);
 7318                         ccb_h->status &= ~CAM_DEV_QFRZN;
 7319                 } else if (runq) {
 7320                         xpt_run_dev_sendq(ccb_h->path->bus);
 7321                 }
 7322 
 7323                 /* Call the peripheral driver's callback */
 7324                 (*ccb_h->cbfcnp)(ccb_h->path->periph, (union ccb *)ccb_h);
 7325         }
 7326 }
 7327 

Cache object: d22aaa7c9e35892873242b0944b4d8a3


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