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


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

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

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

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

Cache object: e10260ee7db3ef6840591fc9b38747c9


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