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


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

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

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

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

Cache object: 46ac8f8f1108cb0fe2601cacbf8189db


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