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/scsi/scsi_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 SCSI Transport
    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/10.4/sys/cam/scsi/scsi_xpt.c 311402 2017-01-05 11:20:31Z mav $");
   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 #include <cam/cam.h>
   51 #include <cam/cam_ccb.h>
   52 #include <cam/cam_queue.h>
   53 #include <cam/cam_periph.h>
   54 #include <cam/cam_sim.h>
   55 #include <cam/cam_xpt.h>
   56 #include <cam/cam_xpt_sim.h>
   57 #include <cam/cam_xpt_periph.h>
   58 #include <cam/cam_xpt_internal.h>
   59 #include <cam/cam_debug.h>
   60 
   61 #include <cam/scsi/scsi_all.h>
   62 #include <cam/scsi/scsi_message.h>
   63 #include <cam/scsi/scsi_pass.h>
   64 #include <machine/stdarg.h>     /* for xpt_print below */
   65 #include "opt_cam.h"
   66 
   67 struct scsi_quirk_entry {
   68         struct scsi_inquiry_pattern inq_pat;
   69         u_int8_t quirks;
   70 #define CAM_QUIRK_NOLUNS        0x01
   71 #define CAM_QUIRK_NOVPDS        0x02
   72 #define CAM_QUIRK_HILUNS        0x04
   73 #define CAM_QUIRK_NOHILUNS      0x08
   74 #define CAM_QUIRK_NORPTLUNS     0x10
   75         u_int mintags;
   76         u_int maxtags;
   77 };
   78 #define SCSI_QUIRK(dev) ((struct scsi_quirk_entry *)((dev)->quirk))
   79 
   80 static int cam_srch_hi = 0;
   81 TUNABLE_INT("kern.cam.cam_srch_hi", &cam_srch_hi);
   82 static int sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS);
   83 SYSCTL_PROC(_kern_cam, OID_AUTO, cam_srch_hi, CTLTYPE_INT|CTLFLAG_RW, 0, 0,
   84     sysctl_cam_search_luns, "I",
   85     "allow search above LUN 7 for SCSI3 and greater devices");
   86 
   87 #define CAM_SCSI2_MAXLUN        8
   88 #define CAM_CAN_GET_SIMPLE_LUN(x, i)                            \
   89         ((((x)->luns[i].lundata[0] & RPL_LUNDATA_ATYP_MASK) ==  \
   90         RPL_LUNDATA_ATYP_PERIPH) ||                             \
   91         (((x)->luns[i].lundata[0] & RPL_LUNDATA_ATYP_MASK) ==   \
   92         RPL_LUNDATA_ATYP_FLAT))
   93 #define CAM_GET_SIMPLE_LUN(lp, i, lval)                                 \
   94         if (((lp)->luns[(i)].lundata[0] & RPL_LUNDATA_ATYP_MASK) ==     \
   95             RPL_LUNDATA_ATYP_PERIPH) {                                  \
   96                 (lval) = (lp)->luns[(i)].lundata[1];                    \
   97         } else {                                                        \
   98                 (lval) = (lp)->luns[(i)].lundata[0];                    \
   99                 (lval) &= RPL_LUNDATA_FLAT_LUN_MASK;                    \
  100                 (lval) <<= 8;                                           \
  101                 (lval) |=  (lp)->luns[(i)].lundata[1];                  \
  102         }
  103 #define CAM_GET_LUN(lp, i, lval)                                        \
  104         (lval) = scsi_4btoul((lp)->luns[(i)].lundata);                  \
  105         (lval) = ((lval) >> 16) | ((lval) << 16);
  106 #define CAM_LUN_ONLY_32BITS(lp, i)                              \
  107         (scsi_4btoul(&((lp)->luns[(i)].lundata[4])) == 0)
  108 
  109 /*
  110  * If we're not quirked to search <= the first 8 luns
  111  * and we are either quirked to search above lun 8,
  112  * or we're > SCSI-2 and we've enabled hilun searching,
  113  * or we're > SCSI-2 and the last lun was a success,
  114  * we can look for luns above lun 8.
  115  */
  116 #define CAN_SRCH_HI_SPARSE(dv)                                  \
  117   (((SCSI_QUIRK(dv)->quirks & CAM_QUIRK_NOHILUNS) == 0)         \
  118   && ((SCSI_QUIRK(dv)->quirks & CAM_QUIRK_HILUNS)               \
  119   || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2 && cam_srch_hi)))
  120 
  121 #define CAN_SRCH_HI_DENSE(dv)                                   \
  122   (((SCSI_QUIRK(dv)->quirks & CAM_QUIRK_NOHILUNS) == 0)         \
  123   && ((SCSI_QUIRK(dv)->quirks & CAM_QUIRK_HILUNS)               \
  124   || (SID_ANSI_REV(&dv->inq_data) > SCSI_REV_2)))
  125 
  126 static periph_init_t probe_periph_init;
  127 
  128 static struct periph_driver probe_driver =
  129 {
  130         probe_periph_init, "probe",
  131         TAILQ_HEAD_INITIALIZER(probe_driver.units), /* generation */ 0,
  132         CAM_PERIPH_DRV_EARLY
  133 };
  134 
  135 PERIPHDRIVER_DECLARE(probe, probe_driver);
  136 
  137 typedef enum {
  138         PROBE_TUR,
  139         PROBE_INQUIRY,  /* this counts as DV0 for Basic Domain Validation */
  140         PROBE_FULL_INQUIRY,
  141         PROBE_REPORT_LUNS,
  142         PROBE_MODE_SENSE,
  143         PROBE_SUPPORTED_VPD_LIST,
  144         PROBE_DEVICE_ID,
  145         PROBE_EXTENDED_INQUIRY,
  146         PROBE_SERIAL_NUM,
  147         PROBE_TUR_FOR_NEGOTIATION,
  148         PROBE_INQUIRY_BASIC_DV1,
  149         PROBE_INQUIRY_BASIC_DV2,
  150         PROBE_DV_EXIT,
  151         PROBE_DONE,
  152         PROBE_INVALID
  153 } probe_action;
  154 
  155 static char *probe_action_text[] = {
  156         "PROBE_TUR",
  157         "PROBE_INQUIRY",
  158         "PROBE_FULL_INQUIRY",
  159         "PROBE_REPORT_LUNS",
  160         "PROBE_MODE_SENSE",
  161         "PROBE_SUPPORTED_VPD_LIST",
  162         "PROBE_DEVICE_ID",
  163         "PROBE_EXTENDED_INQUIRY",
  164         "PROBE_SERIAL_NUM",
  165         "PROBE_TUR_FOR_NEGOTIATION",
  166         "PROBE_INQUIRY_BASIC_DV1",
  167         "PROBE_INQUIRY_BASIC_DV2",
  168         "PROBE_DV_EXIT",
  169         "PROBE_DONE",
  170         "PROBE_INVALID"
  171 };
  172 
  173 #define PROBE_SET_ACTION(softc, newaction)      \
  174 do {                                                                    \
  175         char **text;                                                    \
  176         text = probe_action_text;                                       \
  177         CAM_DEBUG((softc)->periph->path, CAM_DEBUG_PROBE,               \
  178             ("Probe %s to %s\n", text[(softc)->action],                 \
  179             text[(newaction)]));                                        \
  180         (softc)->action = (newaction);                                  \
  181 } while(0)
  182 
  183 typedef enum {
  184         PROBE_INQUIRY_CKSUM     = 0x01,
  185         PROBE_SERIAL_CKSUM      = 0x02,
  186         PROBE_NO_ANNOUNCE       = 0x04,
  187         PROBE_EXTLUN            = 0x08
  188 } probe_flags;
  189 
  190 typedef struct {
  191         TAILQ_HEAD(, ccb_hdr) request_ccbs;
  192         probe_action    action;
  193         union ccb       saved_ccb;
  194         probe_flags     flags;
  195         MD5_CTX         context;
  196         u_int8_t        digest[16];
  197         struct cam_periph *periph;
  198 } probe_softc;
  199 
  200 static const char quantum[] = "QUANTUM";
  201 static const char sony[] = "SONY";
  202 static const char west_digital[] = "WDIGTL";
  203 static const char samsung[] = "SAMSUNG";
  204 static const char seagate[] = "SEAGATE";
  205 static const char microp[] = "MICROP";
  206 
  207 static struct scsi_quirk_entry scsi_quirk_table[] =
  208 {
  209         {
  210                 /* Reports QUEUE FULL for temporary resource shortages */
  211                 { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP39100*", "*" },
  212                 /*quirks*/0, /*mintags*/24, /*maxtags*/32
  213         },
  214         {
  215                 /* Reports QUEUE FULL for temporary resource shortages */
  216                 { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP34550*", "*" },
  217                 /*quirks*/0, /*mintags*/24, /*maxtags*/32
  218         },
  219         {
  220                 /* Reports QUEUE FULL for temporary resource shortages */
  221                 { T_DIRECT, SIP_MEDIA_FIXED, quantum, "XP32275*", "*" },
  222                 /*quirks*/0, /*mintags*/24, /*maxtags*/32
  223         },
  224         {
  225                 /* Broken tagged queuing drive */
  226                 { T_DIRECT, SIP_MEDIA_FIXED, microp, "4421-07*", "*" },
  227                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  228         },
  229         {
  230                 /* Broken tagged queuing drive */
  231                 { T_DIRECT, SIP_MEDIA_FIXED, "HP", "C372*", "*" },
  232                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  233         },
  234         {
  235                 /* Broken tagged queuing drive */
  236                 { T_DIRECT, SIP_MEDIA_FIXED, microp, "3391*", "x43h" },
  237                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  238         },
  239         {
  240                 /*
  241                  * Unfortunately, the Quantum Atlas III has the same
  242                  * problem as the Atlas II drives above.
  243                  * Reported by: "Johan Granlund" <johan@granlund.nu>
  244                  *
  245                  * For future reference, the drive with the problem was:
  246                  * QUANTUM QM39100TD-SW N1B0
  247                  *
  248                  * It's possible that Quantum will fix the problem in later
  249                  * firmware revisions.  If that happens, the quirk entry
  250                  * will need to be made specific to the firmware revisions
  251                  * with the problem.
  252                  *
  253                  */
  254                 /* Reports QUEUE FULL for temporary resource shortages */
  255                 { T_DIRECT, SIP_MEDIA_FIXED, quantum, "QM39100*", "*" },
  256                 /*quirks*/0, /*mintags*/24, /*maxtags*/32
  257         },
  258         {
  259                 /*
  260                  * 18 Gig Atlas III, same problem as the 9G version.
  261                  * Reported by: Andre Albsmeier
  262                  *              <andre.albsmeier@mchp.siemens.de>
  263                  *
  264                  * For future reference, the drive with the problem was:
  265                  * QUANTUM QM318000TD-S N491
  266                  */
  267                 /* Reports QUEUE FULL for temporary resource shortages */
  268                 { T_DIRECT, SIP_MEDIA_FIXED, quantum, "QM318000*", "*" },
  269                 /*quirks*/0, /*mintags*/24, /*maxtags*/32
  270         },
  271         {
  272                 /*
  273                  * Broken tagged queuing drive
  274                  * Reported by: Bret Ford <bford@uop.cs.uop.edu>
  275                  *         and: Martin Renters <martin@tdc.on.ca>
  276                  */
  277                 { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST410800*", "71*" },
  278                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  279         },
  280                 /*
  281                  * The Seagate Medalist Pro drives have very poor write
  282                  * performance with anything more than 2 tags.
  283                  *
  284                  * Reported by:  Paul van der Zwan <paulz@trantor.xs4all.nl>
  285                  * Drive:  <SEAGATE ST36530N 1444>
  286                  *
  287                  * Reported by:  Jeremy Lea <reg@shale.csir.co.za>
  288                  * Drive:  <SEAGATE ST34520W 1281>
  289                  *
  290                  * No one has actually reported that the 9G version
  291                  * (ST39140*) of the Medalist Pro has the same problem, but
  292                  * we're assuming that it does because the 4G and 6.5G
  293                  * versions of the drive are broken.
  294                  */
  295         {
  296                 { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST34520*", "*"},
  297                 /*quirks*/0, /*mintags*/2, /*maxtags*/2
  298         },
  299         {
  300                 { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST36530*", "*"},
  301                 /*quirks*/0, /*mintags*/2, /*maxtags*/2
  302         },
  303         {
  304                 { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST39140*", "*"},
  305                 /*quirks*/0, /*mintags*/2, /*maxtags*/2
  306         },
  307         {
  308                 /*
  309                  * Experiences command timeouts under load with a
  310                  * tag count higher than 55.
  311                  */
  312                 { T_DIRECT, SIP_MEDIA_FIXED, seagate, "ST3146855LW", "*"},
  313                 /*quirks*/0, /*mintags*/2, /*maxtags*/55
  314         },
  315         {
  316                 /*
  317                  * Slow when tagged queueing is enabled.  Write performance
  318                  * steadily drops off with more and more concurrent
  319                  * transactions.  Best sequential write performance with
  320                  * tagged queueing turned off and write caching turned on.
  321                  *
  322                  * PR:  kern/10398
  323                  * Submitted by:  Hideaki Okada <hokada@isl.melco.co.jp>
  324                  * Drive:  DCAS-34330 w/ "S65A" firmware.
  325                  *
  326                  * The drive with the problem had the "S65A" firmware
  327                  * revision, and has also been reported (by Stephen J.
  328                  * Roznowski <sjr@home.net>) for a drive with the "S61A"
  329                  * firmware revision.
  330                  *
  331                  * Although no one has reported problems with the 2 gig
  332                  * version of the DCAS drive, the assumption is that it
  333                  * has the same problems as the 4 gig version.  Therefore
  334                  * this quirk entries disables tagged queueing for all
  335                  * DCAS drives.
  336                  */
  337                 { T_DIRECT, SIP_MEDIA_FIXED, "IBM", "DCAS*", "*" },
  338                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  339         },
  340         {
  341                 /* Broken tagged queuing drive */
  342                 { T_DIRECT, SIP_MEDIA_REMOVABLE, "iomega", "jaz*", "*" },
  343                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  344         },
  345         {
  346                 /* Broken tagged queuing drive */
  347                 { T_DIRECT, SIP_MEDIA_FIXED, "CONNER", "CFP2107*", "*" },
  348                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  349         },
  350         {
  351                 /* This does not support other than LUN 0 */
  352                 { T_DIRECT, SIP_MEDIA_FIXED, "VMware*", "*", "*" },
  353                 CAM_QUIRK_NOLUNS, /*mintags*/2, /*maxtags*/255
  354         },
  355         {
  356                 /*
  357                  * Broken tagged queuing drive.
  358                  * Submitted by:
  359                  * NAKAJI Hiroyuki <nakaji@zeisei.dpri.kyoto-u.ac.jp>
  360                  * in PR kern/9535
  361                  */
  362                 { T_DIRECT, SIP_MEDIA_FIXED, samsung, "WN34324U*", "*" },
  363                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  364         },
  365         {
  366                 /*
  367                  * Slow when tagged queueing is enabled. (1.5MB/sec versus
  368                  * 8MB/sec.)
  369                  * Submitted by: Andrew Gallatin <gallatin@cs.duke.edu>
  370                  * Best performance with these drives is achieved with
  371                  * tagged queueing turned off, and write caching turned on.
  372                  */
  373                 { T_DIRECT, SIP_MEDIA_FIXED, west_digital, "WDE*", "*" },
  374                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  375         },
  376         {
  377                 /*
  378                  * Slow when tagged queueing is enabled. (1.5MB/sec versus
  379                  * 8MB/sec.)
  380                  * Submitted by: Andrew Gallatin <gallatin@cs.duke.edu>
  381                  * Best performance with these drives is achieved with
  382                  * tagged queueing turned off, and write caching turned on.
  383                  */
  384                 { T_DIRECT, SIP_MEDIA_FIXED, west_digital, "ENTERPRISE", "*" },
  385                 /*quirks*/0, /*mintags*/0, /*maxtags*/
  386         },
  387         {
  388                 /*
  389                  * Doesn't handle queue full condition correctly,
  390                  * so we need to limit maxtags to what the device
  391                  * can handle instead of determining this automatically.
  392                  */
  393                 { T_DIRECT, SIP_MEDIA_FIXED, samsung, "WN321010S*", "*" },
  394                 /*quirks*/0, /*mintags*/2, /*maxtags*/32
  395         },
  396         {
  397                 /* Really only one LUN */
  398                 { T_ENCLOSURE, SIP_MEDIA_FIXED, "SUN", "SENA", "*" },
  399                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  400         },
  401         {
  402                 /* I can't believe we need a quirk for DPT volumes. */
  403                 { T_ANY, SIP_MEDIA_FIXED|SIP_MEDIA_REMOVABLE, "DPT", "*", "*" },
  404                 CAM_QUIRK_NOLUNS,
  405                 /*mintags*/0, /*maxtags*/255
  406         },
  407         {
  408                 /*
  409                  * Many Sony CDROM drives don't like multi-LUN probing.
  410                  */
  411                 { T_CDROM, SIP_MEDIA_REMOVABLE, sony, "CD-ROM CDU*", "*" },
  412                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  413         },
  414         {
  415                 /*
  416                  * This drive doesn't like multiple LUN probing.
  417                  * Submitted by:  Parag Patel <parag@cgt.com>
  418                  */
  419                 { T_WORM, SIP_MEDIA_REMOVABLE, sony, "CD-R   CDU9*", "*" },
  420                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  421         },
  422         {
  423                 { T_WORM, SIP_MEDIA_REMOVABLE, "YAMAHA", "CDR100*", "*" },
  424                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  425         },
  426         {
  427                 /*
  428                  * The 8200 doesn't like multi-lun probing, and probably
  429                  * don't like serial number requests either.
  430                  */
  431                 {
  432                         T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "EXABYTE",
  433                         "EXB-8200*", "*"
  434                 },
  435                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  436         },
  437         {
  438                 /*
  439                  * Let's try the same as above, but for a drive that says
  440                  * it's an IPL-6860 but is actually an EXB 8200.
  441                  */
  442                 {
  443                         T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "EXABYTE",
  444                         "IPL-6860*", "*"
  445                 },
  446                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  447         },
  448         {
  449                 /*
  450                  * These Hitachi drives don't like multi-lun probing.
  451                  * The PR submitter has a DK319H, but says that the Linux
  452                  * kernel has a similar work-around for the DK312 and DK314,
  453                  * so all DK31* drives are quirked here.
  454                  * PR:            misc/18793
  455                  * Submitted by:  Paul Haddad <paul@pth.com>
  456                  */
  457                 { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "DK31*", "*" },
  458                 CAM_QUIRK_NOLUNS, /*mintags*/2, /*maxtags*/255
  459         },
  460         {
  461                 /*
  462                  * The Hitachi CJ series with J8A8 firmware apparently has
  463                  * problems with tagged commands.
  464                  * PR: 23536
  465                  * Reported by: amagai@nue.org
  466                  */
  467                 { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "DK32CJ*", "J8A8" },
  468                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  469         },
  470         {
  471                 /*
  472                  * These are the large storage arrays.
  473                  * Submitted by:  William Carrel <william.carrel@infospace.com>
  474                  */
  475                 { T_DIRECT, SIP_MEDIA_FIXED, "HITACHI", "OPEN*", "*" },
  476                 CAM_QUIRK_HILUNS, 2, 1024
  477         },
  478         {
  479                 /*
  480                  * This old revision of the TDC3600 is also SCSI-1, and
  481                  * hangs upon serial number probing.
  482                  */
  483                 {
  484                         T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "TANDBERG",
  485                         " TDC 3600", "U07:"
  486                 },
  487                 CAM_QUIRK_NOVPDS, /*mintags*/0, /*maxtags*/
  488         },
  489         {
  490                 /*
  491                  * Would repond to all LUNs if asked for.
  492                  */
  493                 {
  494                         T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "CALIPER",
  495                         "CP150", "*"
  496                 },
  497                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  498         },
  499         {
  500                 /*
  501                  * Would repond to all LUNs if asked for.
  502                  */
  503                 {
  504                         T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "KENNEDY",
  505                         "96X2*", "*"
  506                 },
  507                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  508         },
  509         {
  510                 /* Submitted by: Matthew Dodd <winter@jurai.net> */
  511                 { T_PROCESSOR, SIP_MEDIA_FIXED, "Cabletrn", "EA41*", "*" },
  512                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  513         },
  514         {
  515                 /* Submitted by: Matthew Dodd <winter@jurai.net> */
  516                 { T_PROCESSOR, SIP_MEDIA_FIXED, "CABLETRN", "EA41*", "*" },
  517                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  518         },
  519         {
  520                 /* TeraSolutions special settings for TRC-22 RAID */
  521                 { T_DIRECT, SIP_MEDIA_FIXED, "TERASOLU", "TRC-22", "*" },
  522                   /*quirks*/0, /*mintags*/55, /*maxtags*/255
  523         },
  524         {
  525                 /* Veritas Storage Appliance */
  526                 { T_DIRECT, SIP_MEDIA_FIXED, "VERITAS", "*", "*" },
  527                   CAM_QUIRK_HILUNS, /*mintags*/2, /*maxtags*/1024
  528         },
  529         {
  530                 /*
  531                  * Would respond to all LUNs.  Device type and removable
  532                  * flag are jumper-selectable.
  533                  */
  534                 { T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED, "MaxOptix",
  535                   "Tahiti 1", "*"
  536                 },
  537                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  538         },
  539         {
  540                 /* EasyRAID E5A aka. areca ARC-6010 */
  541                 { T_DIRECT, SIP_MEDIA_FIXED, "easyRAID", "*", "*" },
  542                   CAM_QUIRK_NOHILUNS, /*mintags*/2, /*maxtags*/255
  543         },
  544         {
  545                 { T_ENCLOSURE, SIP_MEDIA_FIXED, "DP", "BACKPLANE", "*" },
  546                 CAM_QUIRK_NOLUNS, /*mintags*/0, /*maxtags*/
  547         },
  548         {
  549                 { T_DIRECT, SIP_MEDIA_REMOVABLE, "Garmin", "*", "*" },
  550                 CAM_QUIRK_NORPTLUNS, /*mintags*/2, /*maxtags*/255
  551         },
  552         {
  553                 /* Default tagged queuing parameters for all devices */
  554                 {
  555                   T_ANY, SIP_MEDIA_REMOVABLE|SIP_MEDIA_FIXED,
  556                   /*vendor*/"*", /*product*/"*", /*revision*/"*"
  557                 },
  558                 /*quirks*/0, /*mintags*/2, /*maxtags*/255
  559         },
  560 };
  561 
  562 static const int scsi_quirk_table_size =
  563         sizeof(scsi_quirk_table) / sizeof(*scsi_quirk_table);
  564 
  565 static cam_status       proberegister(struct cam_periph *periph,
  566                                       void *arg);
  567 static void      probeschedule(struct cam_periph *probe_periph);
  568 static void      probestart(struct cam_periph *periph, union ccb *start_ccb);
  569 static void      proberequestdefaultnegotiation(struct cam_periph *periph);
  570 static int       proberequestbackoff(struct cam_periph *periph,
  571                                      struct cam_ed *device);
  572 static void      probedone(struct cam_periph *periph, union ccb *done_ccb);
  573 static void      probe_purge_old(struct cam_path *path,
  574                                  struct scsi_report_luns_data *new,
  575                                  probe_flags flags);
  576 static void      probecleanup(struct cam_periph *periph);
  577 static void      scsi_find_quirk(struct cam_ed *device);
  578 static void      scsi_scan_bus(struct cam_periph *periph, union ccb *ccb);
  579 static void      scsi_scan_lun(struct cam_periph *periph,
  580                                struct cam_path *path, cam_flags flags,
  581                                union ccb *ccb);
  582 static void      xptscandone(struct cam_periph *periph, union ccb *done_ccb);
  583 static struct cam_ed *
  584                  scsi_alloc_device(struct cam_eb *bus, struct cam_et *target,
  585                                    lun_id_t lun_id);
  586 static void      scsi_devise_transport(struct cam_path *path);
  587 static void      scsi_set_transfer_settings(struct ccb_trans_settings *cts,
  588                                             struct cam_path *path,
  589                                             int async_update);
  590 static void      scsi_toggle_tags(struct cam_path *path);
  591 static void      scsi_dev_async(u_int32_t async_code,
  592                                 struct cam_eb *bus,
  593                                 struct cam_et *target,
  594                                 struct cam_ed *device,
  595                                 void *async_arg);
  596 static void      scsi_action(union ccb *start_ccb);
  597 static void      scsi_announce_periph(struct cam_periph *periph);
  598 
  599 static struct xpt_xport scsi_xport = {
  600         .alloc_device = scsi_alloc_device,
  601         .action = scsi_action,
  602         .async = scsi_dev_async,
  603         .announce = scsi_announce_periph,
  604 };
  605 
  606 struct xpt_xport *
  607 scsi_get_xport(void)
  608 {
  609         return (&scsi_xport);
  610 }
  611 
  612 static void
  613 probe_periph_init()
  614 {
  615 }
  616 
  617 static cam_status
  618 proberegister(struct cam_periph *periph, void *arg)
  619 {
  620         union ccb *request_ccb; /* CCB representing the probe request */
  621         cam_status status;
  622         probe_softc *softc;
  623 
  624         request_ccb = (union ccb *)arg;
  625         if (request_ccb == NULL) {
  626                 printf("proberegister: no probe CCB, "
  627                        "can't register device\n");
  628                 return(CAM_REQ_CMP_ERR);
  629         }
  630 
  631         softc = (probe_softc *)malloc(sizeof(*softc), M_CAMXPT, M_NOWAIT);
  632 
  633         if (softc == NULL) {
  634                 printf("proberegister: Unable to probe new device. "
  635                        "Unable to allocate softc\n");
  636                 return(CAM_REQ_CMP_ERR);
  637         }
  638         TAILQ_INIT(&softc->request_ccbs);
  639         TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h,
  640                           periph_links.tqe);
  641         softc->flags = 0;
  642         periph->softc = softc;
  643         softc->periph = periph;
  644         softc->action = PROBE_INVALID;
  645         status = cam_periph_acquire(periph);
  646         if (status != CAM_REQ_CMP) {
  647                 return (status);
  648         }
  649         CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe started\n"));
  650         scsi_devise_transport(periph->path);
  651 
  652         /*
  653          * Ensure we've waited at least a bus settle
  654          * delay before attempting to probe the device.
  655          * For HBAs that don't do bus resets, this won't make a difference.
  656          */
  657         cam_periph_freeze_after_event(periph, &periph->path->bus->last_reset,
  658                                       scsi_delay);
  659         probeschedule(periph);
  660         return(CAM_REQ_CMP);
  661 }
  662 
  663 static void
  664 probeschedule(struct cam_periph *periph)
  665 {
  666         struct ccb_pathinq cpi;
  667         union ccb *ccb;
  668         probe_softc *softc;
  669 
  670         softc = (probe_softc *)periph->softc;
  671         ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
  672 
  673         xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NONE);
  674         cpi.ccb_h.func_code = XPT_PATH_INQ;
  675         xpt_action((union ccb *)&cpi);
  676 
  677         /*
  678          * If a device has gone away and another device, or the same one,
  679          * is back in the same place, it should have a unit attention
  680          * condition pending.  It will not report the unit attention in
  681          * response to an inquiry, which may leave invalid transfer
  682          * negotiations in effect.  The TUR will reveal the unit attention
  683          * condition.  Only send the TUR for lun 0, since some devices
  684          * will get confused by commands other than inquiry to non-existent
  685          * luns.  If you think a device has gone away start your scan from
  686          * lun 0.  This will insure that any bogus transfer settings are
  687          * invalidated.
  688          *
  689          * If we haven't seen the device before and the controller supports
  690          * some kind of transfer negotiation, negotiate with the first
  691          * sent command if no bus reset was performed at startup.  This
  692          * ensures that the device is not confused by transfer negotiation
  693          * settings left over by loader or BIOS action.
  694          */
  695         if (((ccb->ccb_h.path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
  696          && (ccb->ccb_h.target_lun == 0)) {
  697                 PROBE_SET_ACTION(softc, PROBE_TUR);
  698         } else if ((cpi.hba_inquiry & (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) != 0
  699               && (cpi.hba_misc & PIM_NOBUSRESET) != 0) {
  700                 proberequestdefaultnegotiation(periph);
  701                 PROBE_SET_ACTION(softc, PROBE_INQUIRY);
  702         } else {
  703                 PROBE_SET_ACTION(softc, PROBE_INQUIRY);
  704         }
  705 
  706         if (ccb->crcn.flags & CAM_EXPECT_INQ_CHANGE)
  707                 softc->flags |= PROBE_NO_ANNOUNCE;
  708         else
  709                 softc->flags &= ~PROBE_NO_ANNOUNCE;
  710 
  711         if (cpi.hba_misc & PIM_EXTLUNS)
  712                 softc->flags |= PROBE_EXTLUN;
  713         else
  714                 softc->flags &= ~PROBE_EXTLUN;
  715 
  716         xpt_schedule(periph, CAM_PRIORITY_XPT);
  717 }
  718 
  719 static void
  720 probestart(struct cam_periph *periph, union ccb *start_ccb)
  721 {
  722         /* Probe the device that our peripheral driver points to */
  723         struct ccb_scsiio *csio;
  724         probe_softc *softc;
  725 
  726         CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probestart\n"));
  727 
  728         softc = (probe_softc *)periph->softc;
  729         csio = &start_ccb->csio;
  730 again:
  731 
  732         switch (softc->action) {
  733         case PROBE_TUR:
  734         case PROBE_TUR_FOR_NEGOTIATION:
  735         case PROBE_DV_EXIT:
  736         {
  737                 scsi_test_unit_ready(csio,
  738                                      /*retries*/4,
  739                                      probedone,
  740                                      MSG_SIMPLE_Q_TAG,
  741                                      SSD_FULL_SIZE,
  742                                      /*timeout*/60000);
  743                 break;
  744         }
  745         case PROBE_INQUIRY:
  746         case PROBE_FULL_INQUIRY:
  747         case PROBE_INQUIRY_BASIC_DV1:
  748         case PROBE_INQUIRY_BASIC_DV2:
  749         {
  750                 u_int inquiry_len;
  751                 struct scsi_inquiry_data *inq_buf;
  752 
  753                 inq_buf = &periph->path->device->inq_data;
  754 
  755                 /*
  756                  * If the device is currently configured, we calculate an
  757                  * MD5 checksum of the inquiry data, and if the serial number
  758                  * length is greater than 0, add the serial number data
  759                  * into the checksum as well.  Once the inquiry and the
  760                  * serial number check finish, we attempt to figure out
  761                  * whether we still have the same device.
  762                  */
  763                 if (((periph->path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
  764                  && ((softc->flags & PROBE_INQUIRY_CKSUM) == 0)) {
  765 
  766                         MD5Init(&softc->context);
  767                         MD5Update(&softc->context, (unsigned char *)inq_buf,
  768                                   sizeof(struct scsi_inquiry_data));
  769                         softc->flags |= PROBE_INQUIRY_CKSUM;
  770                         if (periph->path->device->serial_num_len > 0) {
  771                                 MD5Update(&softc->context,
  772                                           periph->path->device->serial_num,
  773                                           periph->path->device->serial_num_len);
  774                                 softc->flags |= PROBE_SERIAL_CKSUM;
  775                         }
  776                         MD5Final(softc->digest, &softc->context);
  777                 }
  778 
  779                 if (softc->action == PROBE_INQUIRY)
  780                         inquiry_len = SHORT_INQUIRY_LENGTH;
  781                 else
  782                         inquiry_len = SID_ADDITIONAL_LENGTH(inq_buf);
  783 
  784                 /*
  785                  * Some parallel SCSI devices fail to send an
  786                  * ignore wide residue message when dealing with
  787                  * odd length inquiry requests.  Round up to be
  788                  * safe.
  789                  */
  790                 inquiry_len = roundup2(inquiry_len, 2);
  791 
  792                 if (softc->action == PROBE_INQUIRY_BASIC_DV1
  793                  || softc->action == PROBE_INQUIRY_BASIC_DV2) {
  794                         inq_buf = malloc(inquiry_len, M_CAMXPT, M_NOWAIT);
  795                 }
  796                 if (inq_buf == NULL) {
  797                         xpt_print(periph->path, "malloc failure- skipping Basic"
  798                             "Domain Validation\n");
  799                         PROBE_SET_ACTION(softc, PROBE_DV_EXIT);
  800                         scsi_test_unit_ready(csio,
  801                                              /*retries*/4,
  802                                              probedone,
  803                                              MSG_SIMPLE_Q_TAG,
  804                                              SSD_FULL_SIZE,
  805                                              /*timeout*/60000);
  806                         break;
  807                 }
  808                 scsi_inquiry(csio,
  809                              /*retries*/4,
  810                              probedone,
  811                              MSG_SIMPLE_Q_TAG,
  812                              (u_int8_t *)inq_buf,
  813                              inquiry_len,
  814                              /*evpd*/FALSE,
  815                              /*page_code*/0,
  816                              SSD_MIN_SIZE,
  817                              /*timeout*/60 * 1000);
  818                 break;
  819         }
  820         case PROBE_REPORT_LUNS:
  821         {
  822                 void *rp;
  823 
  824                 rp = malloc(periph->path->target->rpl_size,
  825                     M_CAMXPT, M_NOWAIT | M_ZERO);
  826                 if (rp == NULL) {
  827                         struct scsi_inquiry_data *inq_buf;
  828                         inq_buf = &periph->path->device->inq_data;
  829                         xpt_print(periph->path,
  830                             "Unable to alloc report luns storage\n");
  831                         if (INQ_DATA_TQ_ENABLED(inq_buf))
  832                                 PROBE_SET_ACTION(softc, PROBE_MODE_SENSE);
  833                         else
  834                                 PROBE_SET_ACTION(softc,
  835                                     PROBE_SUPPORTED_VPD_LIST);
  836                         goto again;
  837                 }
  838                 scsi_report_luns(csio, 5, probedone, MSG_SIMPLE_Q_TAG,
  839                     RPL_REPORT_DEFAULT, rp, periph->path->target->rpl_size,
  840                     SSD_FULL_SIZE, 60000); break;
  841                 break;
  842         }
  843         case PROBE_MODE_SENSE:
  844         {
  845                 void  *mode_buf;
  846                 int    mode_buf_len;
  847 
  848                 mode_buf_len = sizeof(struct scsi_mode_header_6)
  849                              + sizeof(struct scsi_mode_blk_desc)
  850                              + sizeof(struct scsi_control_page);
  851                 mode_buf = malloc(mode_buf_len, M_CAMXPT, M_NOWAIT);
  852                 if (mode_buf != NULL) {
  853                         scsi_mode_sense(csio,
  854                                         /*retries*/4,
  855                                         probedone,
  856                                         MSG_SIMPLE_Q_TAG,
  857                                         /*dbd*/FALSE,
  858                                         SMS_PAGE_CTRL_CURRENT,
  859                                         SMS_CONTROL_MODE_PAGE,
  860                                         mode_buf,
  861                                         mode_buf_len,
  862                                         SSD_FULL_SIZE,
  863                                         /*timeout*/60000);
  864                         break;
  865                 }
  866                 xpt_print(periph->path, "Unable to mode sense control page - "
  867                     "malloc failure\n");
  868                 PROBE_SET_ACTION(softc, PROBE_SUPPORTED_VPD_LIST);
  869         }
  870         /* FALLTHROUGH */
  871         case PROBE_SUPPORTED_VPD_LIST:
  872         {
  873                 struct scsi_vpd_supported_page_list *vpd_list;
  874                 struct cam_ed *device;
  875 
  876                 vpd_list = NULL;
  877                 device = periph->path->device;
  878 
  879                 if ((SCSI_QUIRK(device)->quirks & CAM_QUIRK_NOVPDS) == 0)
  880                         vpd_list = malloc(sizeof(*vpd_list), M_CAMXPT,
  881                             M_NOWAIT | M_ZERO);
  882 
  883                 if (vpd_list != NULL) {
  884                         scsi_inquiry(csio,
  885                                      /*retries*/4,
  886                                      probedone,
  887                                      MSG_SIMPLE_Q_TAG,
  888                                      (u_int8_t *)vpd_list,
  889                                      sizeof(*vpd_list),
  890                                      /*evpd*/TRUE,
  891                                      SVPD_SUPPORTED_PAGE_LIST,
  892                                      SSD_MIN_SIZE,
  893                                      /*timeout*/60 * 1000);
  894                         break;
  895                 }
  896 done:
  897                 /*
  898                  * We'll have to do without, let our probedone
  899                  * routine finish up for us.
  900                  */
  901                 start_ccb->csio.data_ptr = NULL;
  902                 cam_freeze_devq(periph->path);
  903                 cam_periph_doacquire(periph);
  904                 probedone(periph, start_ccb);
  905                 return;
  906         }
  907         case PROBE_DEVICE_ID:
  908         {
  909                 struct scsi_vpd_device_id *devid;
  910 
  911                 devid = NULL;
  912                 if (scsi_vpd_supported_page(periph, SVPD_DEVICE_ID))
  913                         devid = malloc(SVPD_DEVICE_ID_MAX_SIZE, M_CAMXPT,
  914                             M_NOWAIT | M_ZERO);
  915 
  916                 if (devid != NULL) {
  917                         scsi_inquiry(csio,
  918                                      /*retries*/4,
  919                                      probedone,
  920                                      MSG_SIMPLE_Q_TAG,
  921                                      (uint8_t *)devid,
  922                                      SVPD_DEVICE_ID_MAX_SIZE,
  923                                      /*evpd*/TRUE,
  924                                      SVPD_DEVICE_ID,
  925                                      SSD_MIN_SIZE,
  926                                      /*timeout*/60 * 1000);
  927                         break;
  928                 }
  929                 goto done;
  930         }
  931         case PROBE_EXTENDED_INQUIRY:
  932         {
  933                 struct scsi_vpd_extended_inquiry_data *ext_inq;
  934 
  935                 ext_inq = NULL;
  936                 if (scsi_vpd_supported_page(periph, SVPD_EXTENDED_INQUIRY_DATA))
  937                         ext_inq = malloc(sizeof(*ext_inq), M_CAMXPT,
  938                             M_NOWAIT | M_ZERO);
  939 
  940                 if (ext_inq != NULL) {
  941                         scsi_inquiry(csio,
  942                                      /*retries*/4,
  943                                      probedone,
  944                                      MSG_SIMPLE_Q_TAG,
  945                                      (uint8_t *)ext_inq,
  946                                      sizeof(*ext_inq),
  947                                      /*evpd*/TRUE,
  948                                      SVPD_EXTENDED_INQUIRY_DATA,
  949                                      SSD_MIN_SIZE,
  950                                      /*timeout*/60 * 1000);
  951                         break;
  952                 }
  953                 /*
  954                  * We'll have to do without, let our probedone
  955                  * routine finish up for us.
  956                  */
  957                 goto done;
  958         }
  959         case PROBE_SERIAL_NUM:
  960         {
  961                 struct scsi_vpd_unit_serial_number *serial_buf;
  962                 struct cam_ed* device;
  963 
  964                 serial_buf = NULL;
  965                 device = periph->path->device;
  966                 if (device->serial_num != NULL) {
  967                         free(device->serial_num, M_CAMXPT);
  968                         device->serial_num = NULL;
  969                         device->serial_num_len = 0;
  970                 }
  971 
  972                 if (scsi_vpd_supported_page(periph, SVPD_UNIT_SERIAL_NUMBER))
  973                         serial_buf = (struct scsi_vpd_unit_serial_number *)
  974                                 malloc(sizeof(*serial_buf), M_CAMXPT,
  975                                     M_NOWAIT|M_ZERO);
  976 
  977                 if (serial_buf != NULL) {
  978                         scsi_inquiry(csio,
  979                                      /*retries*/4,
  980                                      probedone,
  981                                      MSG_SIMPLE_Q_TAG,
  982                                      (u_int8_t *)serial_buf,
  983                                      sizeof(*serial_buf),
  984                                      /*evpd*/TRUE,
  985                                      SVPD_UNIT_SERIAL_NUMBER,
  986                                      SSD_MIN_SIZE,
  987                                      /*timeout*/60 * 1000);
  988                         break;
  989                 }
  990                 goto done;
  991         }
  992         default:
  993                 panic("probestart: invalid action state 0x%x\n", softc->action);
  994         }
  995         start_ccb->ccb_h.flags |= CAM_DEV_QFREEZE;
  996         cam_periph_doacquire(periph);
  997         xpt_action(start_ccb);
  998 }
  999 
 1000 static void
 1001 proberequestdefaultnegotiation(struct cam_periph *periph)
 1002 {
 1003         struct ccb_trans_settings cts;
 1004 
 1005         xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE);
 1006         cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 1007         cts.type = CTS_TYPE_USER_SETTINGS;
 1008         xpt_action((union ccb *)&cts);
 1009         if (cam_ccb_status((union ccb *)&cts) != CAM_REQ_CMP) {
 1010                 return;
 1011         }
 1012         cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
 1013         cts.type = CTS_TYPE_CURRENT_SETTINGS;
 1014         xpt_action((union ccb *)&cts);
 1015 }
 1016 
 1017 /*
 1018  * Backoff Negotiation Code- only pertinent for SPI devices.
 1019  */
 1020 static int
 1021 proberequestbackoff(struct cam_periph *periph, struct cam_ed *device)
 1022 {
 1023         struct ccb_trans_settings cts;
 1024         struct ccb_trans_settings_spi *spi;
 1025 
 1026         memset(&cts, 0, sizeof (cts));
 1027         xpt_setup_ccb(&cts.ccb_h, periph->path, CAM_PRIORITY_NONE);
 1028         cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 1029         cts.type = CTS_TYPE_CURRENT_SETTINGS;
 1030         xpt_action((union ccb *)&cts);
 1031         if (cam_ccb_status((union ccb *)&cts) != CAM_REQ_CMP) {
 1032                 if (bootverbose) {
 1033                         xpt_print(periph->path,
 1034                             "failed to get current device settings\n");
 1035                 }
 1036                 return (0);
 1037         }
 1038         if (cts.transport != XPORT_SPI) {
 1039                 if (bootverbose) {
 1040                         xpt_print(periph->path, "not SPI transport\n");
 1041                 }
 1042                 return (0);
 1043         }
 1044         spi = &cts.xport_specific.spi;
 1045 
 1046         /*
 1047          * We cannot renegotiate sync rate if we don't have one.
 1048          */
 1049         if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0) {
 1050                 if (bootverbose) {
 1051                         xpt_print(periph->path, "no sync rate known\n");
 1052                 }
 1053                 return (0);
 1054         }
 1055 
 1056         /*
 1057          * We'll assert that we don't have to touch PPR options- the
 1058          * SIM will see what we do with period and offset and adjust
 1059          * the PPR options as appropriate.
 1060          */
 1061 
 1062         /*
 1063          * A sync rate with unknown or zero offset is nonsensical.
 1064          * A sync period of zero means Async.
 1065          */
 1066         if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0
 1067          || spi->sync_offset == 0 || spi->sync_period == 0) {
 1068                 if (bootverbose) {
 1069                         xpt_print(periph->path, "no sync rate available\n");
 1070                 }
 1071                 return (0);
 1072         }
 1073 
 1074         if (device->flags & CAM_DEV_DV_HIT_BOTTOM) {
 1075                 CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
 1076                     ("hit async: giving up on DV\n"));
 1077                 return (0);
 1078         }
 1079 
 1080 
 1081         /*
 1082          * Jump sync_period up by one, but stop at 5MHz and fall back to Async.
 1083          * We don't try to remember 'last' settings to see if the SIM actually
 1084          * gets into the speed we want to set. We check on the SIM telling
 1085          * us that a requested speed is bad, but otherwise don't try and
 1086          * check the speed due to the asynchronous and handshake nature
 1087          * of speed setting.
 1088          */
 1089         spi->valid = CTS_SPI_VALID_SYNC_RATE | CTS_SPI_VALID_SYNC_OFFSET;
 1090         for (;;) {
 1091                 spi->sync_period++;
 1092                 if (spi->sync_period >= 0xf) {
 1093                         spi->sync_period = 0;
 1094                         spi->sync_offset = 0;
 1095                         CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
 1096                             ("setting to async for DV\n"));
 1097                         /*
 1098                          * Once we hit async, we don't want to try
 1099                          * any more settings.
 1100                          */
 1101                         device->flags |= CAM_DEV_DV_HIT_BOTTOM;
 1102                 } else if (bootverbose) {
 1103                         CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
 1104                             ("DV: period 0x%x\n", spi->sync_period));
 1105                         printf("setting period to 0x%x\n", spi->sync_period);
 1106                 }
 1107                 cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
 1108                 cts.type = CTS_TYPE_CURRENT_SETTINGS;
 1109                 xpt_action((union ccb *)&cts);
 1110                 if (cam_ccb_status((union ccb *)&cts) != CAM_REQ_CMP) {
 1111                         break;
 1112                 }
 1113                 CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
 1114                     ("DV: failed to set period 0x%x\n", spi->sync_period));
 1115                 if (spi->sync_period == 0) {
 1116                         return (0);
 1117                 }
 1118         }
 1119         return (1);
 1120 }
 1121 
 1122 #define CCB_COMPLETED_OK(ccb) (((ccb).status & CAM_STATUS_MASK) == CAM_REQ_CMP)
 1123 
 1124 static void
 1125 probedone(struct cam_periph *periph, union ccb *done_ccb)
 1126 {
 1127         probe_softc *softc;
 1128         struct cam_path *path;
 1129         struct scsi_inquiry_data *inq_buf;
 1130         u_int32_t  priority;
 1131 
 1132         CAM_DEBUG(done_ccb->ccb_h.path, CAM_DEBUG_TRACE, ("probedone\n"));
 1133 
 1134         softc = (probe_softc *)periph->softc;
 1135         path = done_ccb->ccb_h.path;
 1136         priority = done_ccb->ccb_h.pinfo.priority;
 1137 
 1138         switch (softc->action) {
 1139         case PROBE_TUR:
 1140         {
 1141                 if (cam_ccb_status(done_ccb) != CAM_REQ_CMP) {
 1142 
 1143                         if (cam_periph_error(done_ccb, 0,
 1144                                              SF_NO_PRINT, NULL) == ERESTART) {
 1145 outr:
 1146                                 /* Drop freeze taken due to CAM_DEV_QFREEZE */
 1147                                 cam_release_devq(path, 0, 0, 0, FALSE);
 1148                                 return;
 1149                         }
 1150                         else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
 1151                                 /* Don't wedge the queue */
 1152                                 xpt_release_devq(done_ccb->ccb_h.path,
 1153                                                  /*count*/1,
 1154                                                  /*run_queue*/TRUE);
 1155                 }
 1156                 PROBE_SET_ACTION(softc, PROBE_INQUIRY);
 1157                 xpt_release_ccb(done_ccb);
 1158                 xpt_schedule(periph, priority);
 1159 out:
 1160                 /* Drop freeze taken due to CAM_DEV_QFREEZE and release. */
 1161                 cam_release_devq(path, 0, 0, 0, FALSE);
 1162                 cam_periph_release_locked(periph);
 1163                 return;
 1164         }
 1165         case PROBE_INQUIRY:
 1166         case PROBE_FULL_INQUIRY:
 1167         {
 1168                 if (cam_ccb_status(done_ccb) == CAM_REQ_CMP) {
 1169                         u_int8_t periph_qual;
 1170 
 1171                         path->device->flags |= CAM_DEV_INQUIRY_DATA_VALID;
 1172                         scsi_find_quirk(path->device);
 1173                         inq_buf = &path->device->inq_data;
 1174 
 1175                         periph_qual = SID_QUAL(inq_buf);
 1176 
 1177                         if (periph_qual == SID_QUAL_LU_CONNECTED ||
 1178                             periph_qual == SID_QUAL_LU_OFFLINE) {
 1179                                 u_int8_t len;
 1180 
 1181                                 /*
 1182                                  * We conservatively request only
 1183                                  * SHORT_INQUIRY_LEN bytes of inquiry
 1184                                  * information during our first try
 1185                                  * at sending an INQUIRY. If the device
 1186                                  * has more information to give,
 1187                                  * perform a second request specifying
 1188                                  * the amount of information the device
 1189                                  * is willing to give.
 1190                                  */
 1191                                 len = inq_buf->additional_length
 1192                                     + offsetof(struct scsi_inquiry_data,
 1193                                                additional_length) + 1;
 1194                                 if (softc->action == PROBE_INQUIRY
 1195                                     && len > SHORT_INQUIRY_LENGTH) {
 1196                                         PROBE_SET_ACTION(softc, PROBE_FULL_INQUIRY);
 1197                                         xpt_release_ccb(done_ccb);
 1198                                         xpt_schedule(periph, priority);
 1199                                         goto out;
 1200                                 }
 1201 
 1202                                 scsi_devise_transport(path);
 1203 
 1204                                 if (path->device->lun_id == 0 &&
 1205                                     SID_ANSI_REV(inq_buf) > SCSI_REV_SPC2 &&
 1206                                     (SCSI_QUIRK(path->device)->quirks &
 1207                                      CAM_QUIRK_NORPTLUNS) == 0) {
 1208                                         PROBE_SET_ACTION(softc,
 1209                                             PROBE_REPORT_LUNS);
 1210                                         /*
 1211                                          * Start with room for *one* lun.
 1212                                          */
 1213                                         periph->path->target->rpl_size = 16;
 1214                                 } else if (INQ_DATA_TQ_ENABLED(inq_buf))
 1215                                         PROBE_SET_ACTION(softc,
 1216                                             PROBE_MODE_SENSE);
 1217                                 else
 1218                                         PROBE_SET_ACTION(softc,
 1219                                             PROBE_SUPPORTED_VPD_LIST);
 1220 
 1221                                 if (path->device->flags & CAM_DEV_UNCONFIGURED) {
 1222                                         path->device->flags &= ~CAM_DEV_UNCONFIGURED;
 1223                                         xpt_acquire_device(path->device);
 1224                                 }
 1225                                 xpt_release_ccb(done_ccb);
 1226                                 xpt_schedule(periph, priority);
 1227                                 goto out;
 1228                         } else if (path->device->lun_id == 0 &&
 1229                             SID_ANSI_REV(inq_buf) >= SCSI_REV_SPC2 &&
 1230                             (SCSI_QUIRK(path->device)->quirks &
 1231                              CAM_QUIRK_NORPTLUNS) == 0) {
 1232                                 PROBE_SET_ACTION(softc, PROBE_REPORT_LUNS);
 1233                                 periph->path->target->rpl_size = 16;
 1234                                 xpt_release_ccb(done_ccb);
 1235                                 xpt_schedule(periph, priority);
 1236                                 goto out;
 1237                         }
 1238                 } else if (cam_periph_error(done_ccb, 0,
 1239                                             done_ccb->ccb_h.target_lun > 0
 1240                                             ? SF_RETRY_UA|SF_QUIET_IR
 1241                                             : SF_RETRY_UA,
 1242                                             &softc->saved_ccb) == ERESTART) {
 1243                         goto outr;
 1244                 } else {
 1245                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 1246                                 /* Don't wedge the queue */
 1247                                 xpt_release_devq(done_ccb->ccb_h.path,
 1248                                     /*count*/1, /*run_queue*/TRUE);
 1249                         }
 1250                         path->device->flags &= ~CAM_DEV_INQUIRY_DATA_VALID;
 1251                 }
 1252                 /*
 1253                  * If we get to this point, we got an error status back
 1254                  * from the inquiry and the error status doesn't require
 1255                  * automatically retrying the command.  Therefore, the
 1256                  * inquiry failed.  If we had inquiry information before
 1257                  * for this device, but this latest inquiry command failed,
 1258                  * the device has probably gone away.  If this device isn't
 1259                  * already marked unconfigured, notify the peripheral
 1260                  * drivers that this device is no more.
 1261                  */
 1262                 if ((path->device->flags & CAM_DEV_UNCONFIGURED) == 0)
 1263                         /* Send the async notification. */
 1264                         xpt_async(AC_LOST_DEVICE, path, NULL);
 1265                 PROBE_SET_ACTION(softc, PROBE_INVALID);
 1266 
 1267                 xpt_release_ccb(done_ccb);
 1268                 break;
 1269         }
 1270         case PROBE_REPORT_LUNS:
 1271         {
 1272                 struct ccb_scsiio *csio;
 1273                 struct scsi_report_luns_data *lp;
 1274                 u_int nlun, maxlun;
 1275 
 1276                 csio = &done_ccb->csio;
 1277 
 1278                 lp = (struct scsi_report_luns_data *)csio->data_ptr;
 1279                 nlun = scsi_4btoul(lp->length) / 8;
 1280                 maxlun = (csio->dxfer_len / 8) - 1;
 1281 
 1282                 if (cam_ccb_status(done_ccb) != CAM_REQ_CMP) {
 1283                         if (cam_periph_error(done_ccb, 0,
 1284                             done_ccb->ccb_h.target_lun > 0 ?
 1285                             SF_RETRY_UA|SF_QUIET_IR : SF_RETRY_UA,
 1286                             &softc->saved_ccb) == ERESTART) {
 1287                                 goto outr;
 1288                         }
 1289                         if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 1290                                 xpt_release_devq(done_ccb->ccb_h.path, 1,
 1291                                     TRUE);
 1292                         }
 1293                         free(lp, M_CAMXPT);
 1294                         lp = NULL;
 1295                 } else if (nlun > maxlun) {
 1296                         /*
 1297                          * Reallocate and retry to cover all luns
 1298                          */
 1299                         CAM_DEBUG(path, CAM_DEBUG_PROBE,
 1300                             ("Probe: reallocating REPORT_LUNS for %u luns\n",
 1301                              nlun));
 1302                         free(lp, M_CAMXPT);
 1303                         path->target->rpl_size = (nlun << 3) + 8;
 1304                         xpt_release_ccb(done_ccb);
 1305                         xpt_schedule(periph, priority);
 1306                         goto out;
 1307                 } else if (nlun == 0) {
 1308                         /*
 1309                          * If there don't appear to be any luns, bail.
 1310                          */
 1311                         free(lp, M_CAMXPT);
 1312                         lp = NULL;
 1313                 } else {
 1314                         lun_id_t lun;
 1315                         int idx;
 1316 
 1317                         CAM_DEBUG(path, CAM_DEBUG_PROBE,
 1318                            ("Probe: %u lun(s) reported\n", nlun));
 1319 
 1320                         CAM_GET_LUN(lp, 0, lun);
 1321                         /*
 1322                          * If the first lun is not lun 0, then either there
 1323                          * is no lun 0 in the list, or the list is unsorted.
 1324                          */
 1325                         if (lun != 0) {
 1326                                 for (idx = 0; idx < nlun; idx++) {
 1327                                         CAM_GET_LUN(lp, idx, lun);
 1328                                         if (lun == 0) {
 1329                                                 break;
 1330                                         }
 1331                                 }
 1332                                 if (idx != nlun) {
 1333                                         uint8_t tlun[8];
 1334                                         memcpy(tlun,
 1335                                             lp->luns[0].lundata, 8);
 1336                                         memcpy(lp->luns[0].lundata,
 1337                                             lp->luns[idx].lundata, 8);
 1338                                         memcpy(lp->luns[idx].lundata,
 1339                                             tlun, 8);
 1340                                         CAM_DEBUG(path, CAM_DEBUG_PROBE,
 1341                                             ("lun 0 in position %u\n", idx));
 1342                                 }
 1343                         }
 1344                         /*
 1345                          * If we have an old lun list, We can either
 1346                          * retest luns that appear to have been dropped,
 1347                          * or just nuke them.  We'll opt for the latter.
 1348                          * This function will also install the new list
 1349                          * in the target structure.
 1350                          */
 1351                         probe_purge_old(path, lp, softc->flags);
 1352                         lp = NULL;
 1353                 }
 1354                 inq_buf = &path->device->inq_data;
 1355                 if (path->device->flags & CAM_DEV_INQUIRY_DATA_VALID &&
 1356                     (SID_QUAL(inq_buf) == SID_QUAL_LU_CONNECTED ||
 1357                     SID_QUAL(inq_buf) == SID_QUAL_LU_OFFLINE)) {
 1358                         if (INQ_DATA_TQ_ENABLED(inq_buf))
 1359                                 PROBE_SET_ACTION(softc, PROBE_MODE_SENSE);
 1360                         else
 1361                                 PROBE_SET_ACTION(softc,
 1362                                     PROBE_SUPPORTED_VPD_LIST);
 1363                         xpt_release_ccb(done_ccb);
 1364                         xpt_schedule(periph, priority);
 1365                         goto out;
 1366                 }
 1367                 if (lp) {
 1368                         free(lp, M_CAMXPT);
 1369                 }
 1370                 PROBE_SET_ACTION(softc, PROBE_INVALID);
 1371                 xpt_release_ccb(done_ccb);
 1372                 break;
 1373         }
 1374         case PROBE_MODE_SENSE:
 1375         {
 1376                 struct ccb_scsiio *csio;
 1377                 struct scsi_mode_header_6 *mode_hdr;
 1378 
 1379                 csio = &done_ccb->csio;
 1380                 mode_hdr = (struct scsi_mode_header_6 *)csio->data_ptr;
 1381                 if (cam_ccb_status(done_ccb) == CAM_REQ_CMP) {
 1382                         struct scsi_control_page *page;
 1383                         u_int8_t *offset;
 1384 
 1385                         offset = ((u_int8_t *)&mode_hdr[1])
 1386                             + mode_hdr->blk_desc_len;
 1387                         page = (struct scsi_control_page *)offset;
 1388                         path->device->queue_flags = page->queue_flags;
 1389                 } else if (cam_periph_error(done_ccb, 0,
 1390                                             SF_RETRY_UA|SF_NO_PRINT,
 1391                                             &softc->saved_ccb) == ERESTART) {
 1392                         goto outr;
 1393                 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 1394                         /* Don't wedge the queue */
 1395                         xpt_release_devq(done_ccb->ccb_h.path,
 1396                                          /*count*/1, /*run_queue*/TRUE);
 1397                 }
 1398                 xpt_release_ccb(done_ccb);
 1399                 free(mode_hdr, M_CAMXPT);
 1400                 PROBE_SET_ACTION(softc, PROBE_SUPPORTED_VPD_LIST);
 1401                 xpt_schedule(periph, priority);
 1402                 goto out;
 1403         }
 1404         case PROBE_SUPPORTED_VPD_LIST:
 1405         {
 1406                 struct ccb_scsiio *csio;
 1407                 struct scsi_vpd_supported_page_list *page_list;
 1408 
 1409                 csio = &done_ccb->csio;
 1410                 page_list =
 1411                     (struct scsi_vpd_supported_page_list *)csio->data_ptr;
 1412 
 1413                 if (path->device->supported_vpds != NULL) {
 1414                         free(path->device->supported_vpds, M_CAMXPT);
 1415                         path->device->supported_vpds = NULL;
 1416                         path->device->supported_vpds_len = 0;
 1417                 }
 1418 
 1419                 if (page_list == NULL) {
 1420                         /*
 1421                          * Don't process the command as it was never sent
 1422                          */
 1423                 } else if (CCB_COMPLETED_OK(csio->ccb_h)) {
 1424                         /* Got vpd list */
 1425                         path->device->supported_vpds_len = page_list->length +
 1426                             SVPD_SUPPORTED_PAGES_HDR_LEN;
 1427                         path->device->supported_vpds = (uint8_t *)page_list;
 1428                         xpt_release_ccb(done_ccb);
 1429                         PROBE_SET_ACTION(softc, PROBE_DEVICE_ID);
 1430                         xpt_schedule(periph, priority);
 1431                         goto out;
 1432                 } else if (cam_periph_error(done_ccb, 0,
 1433                                             SF_RETRY_UA|SF_NO_PRINT,
 1434                                             &softc->saved_ccb) == ERESTART) {
 1435                         goto outr;
 1436                 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 1437                         /* Don't wedge the queue */
 1438                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 1439                                          /*run_queue*/TRUE);
 1440                 }
 1441 
 1442                 if (page_list)
 1443                         free(page_list, M_CAMXPT);
 1444                 /* No VPDs available, skip to device check. */
 1445                 csio->data_ptr = NULL;
 1446                 goto probe_device_check;
 1447         }
 1448         case PROBE_DEVICE_ID:
 1449         {
 1450                 struct scsi_vpd_device_id *devid;
 1451                 struct ccb_scsiio *csio;
 1452                 uint32_t length = 0;
 1453 
 1454                 csio = &done_ccb->csio;
 1455                 devid = (struct scsi_vpd_device_id *)csio->data_ptr;
 1456 
 1457                 /* Clean up from previous instance of this device */
 1458                 if (path->device->device_id != NULL) {
 1459                         path->device->device_id_len = 0;
 1460                         free(path->device->device_id, M_CAMXPT);
 1461                         path->device->device_id = NULL;
 1462                 }
 1463 
 1464                 if (devid == NULL) {
 1465                         /* Don't process the command as it was never sent */
 1466                 } else if (CCB_COMPLETED_OK(csio->ccb_h)) {
 1467                         length = scsi_2btoul(devid->length);
 1468                         if (length != 0) {
 1469                                 /*
 1470                                  * NB: device_id_len is actual response
 1471                                  * size, not buffer size.
 1472                                  */
 1473                                 path->device->device_id_len = length +
 1474                                     SVPD_DEVICE_ID_HDR_LEN;
 1475                                 path->device->device_id = (uint8_t *)devid;
 1476                         }
 1477                 } else if (cam_periph_error(done_ccb, 0,
 1478                                             SF_RETRY_UA,
 1479                                             &softc->saved_ccb) == ERESTART) {
 1480                         goto outr;
 1481                 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 1482                         /* Don't wedge the queue */
 1483                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 1484                                          /*run_queue*/TRUE);
 1485                 }
 1486 
 1487                 /* Free the device id space if we don't use it */
 1488                 if (devid && length == 0)
 1489                         free(devid, M_CAMXPT);
 1490                 xpt_release_ccb(done_ccb);
 1491                 PROBE_SET_ACTION(softc, PROBE_EXTENDED_INQUIRY);
 1492                 xpt_schedule(periph, priority);
 1493                 goto out;
 1494         }
 1495         case PROBE_EXTENDED_INQUIRY: {
 1496                 struct scsi_vpd_extended_inquiry_data *ext_inq;
 1497                 struct ccb_scsiio *csio;
 1498                 int32_t length = 0;
 1499 
 1500                 csio = &done_ccb->csio;
 1501                 ext_inq = (struct scsi_vpd_extended_inquiry_data *)
 1502                     csio->data_ptr;
 1503                 if (path->device->ext_inq != NULL) {
 1504                         path->device->ext_inq_len = 0;
 1505                         free(path->device->ext_inq, M_CAMXPT);
 1506                         path->device->ext_inq = NULL;
 1507                 }
 1508 
 1509                 if (ext_inq == NULL) {
 1510                         /* Don't process the command as it was never sent */
 1511                 } else if (CCB_COMPLETED_OK(csio->ccb_h)) {
 1512                         length = scsi_2btoul(ext_inq->page_length) +
 1513                             __offsetof(struct scsi_vpd_extended_inquiry_data,
 1514                             flags1);
 1515                         length = min(length, sizeof(*ext_inq));
 1516                         length -= csio->resid;
 1517                         if (length > 0) {
 1518                                 path->device->ext_inq_len = length;
 1519                                 path->device->ext_inq = (uint8_t *)ext_inq;
 1520                         }
 1521                 } else if (cam_periph_error(done_ccb, 0,
 1522                                             SF_RETRY_UA,
 1523                                             &softc->saved_ccb) == ERESTART) {
 1524                         goto outr;
 1525                 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 1526                         /* Don't wedge the queue */
 1527                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 1528                                          /*run_queue*/TRUE);
 1529                 }
 1530 
 1531                 /* Free the device id space if we don't use it */
 1532                 if (ext_inq && length <= 0)
 1533                         free(ext_inq, M_CAMXPT);
 1534                 xpt_release_ccb(done_ccb);
 1535                 PROBE_SET_ACTION(softc, PROBE_SERIAL_NUM);
 1536                 xpt_schedule(periph, priority);
 1537                 goto out;
 1538         }
 1539 
 1540 probe_device_check:
 1541         case PROBE_SERIAL_NUM:
 1542         {
 1543                 struct ccb_scsiio *csio;
 1544                 struct scsi_vpd_unit_serial_number *serial_buf;
 1545                 u_int32_t  priority;
 1546                 int changed;
 1547                 int have_serialnum;
 1548 
 1549                 changed = 1;
 1550                 have_serialnum = 0;
 1551                 csio = &done_ccb->csio;
 1552                 priority = done_ccb->ccb_h.pinfo.priority;
 1553                 serial_buf =
 1554                     (struct scsi_vpd_unit_serial_number *)csio->data_ptr;
 1555 
 1556                 if (serial_buf == NULL) {
 1557                         /*
 1558                          * Don't process the command as it was never sent
 1559                          */
 1560                 } else if (cam_ccb_status(done_ccb) == CAM_REQ_CMP
 1561                         && (serial_buf->length > 0)) {
 1562 
 1563                         have_serialnum = 1;
 1564                         path->device->serial_num =
 1565                                 (u_int8_t *)malloc((serial_buf->length + 1),
 1566                                                    M_CAMXPT, M_NOWAIT);
 1567                         if (path->device->serial_num != NULL) {
 1568                                 memcpy(path->device->serial_num,
 1569                                        serial_buf->serial_num,
 1570                                        serial_buf->length);
 1571                                 path->device->serial_num_len =
 1572                                     serial_buf->length;
 1573                                 path->device->serial_num[serial_buf->length]
 1574                                     = '\0';
 1575                         }
 1576                 } else if (cam_periph_error(done_ccb, 0,
 1577                                             SF_RETRY_UA|SF_NO_PRINT,
 1578                                             &softc->saved_ccb) == ERESTART) {
 1579                         goto outr;
 1580                 } else if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 1581                         /* Don't wedge the queue */
 1582                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 1583                                          /*run_queue*/TRUE);
 1584                 }
 1585 
 1586                 /*
 1587                  * Let's see if we have seen this device before.
 1588                  */
 1589                 if ((softc->flags & PROBE_INQUIRY_CKSUM) != 0) {
 1590                         MD5_CTX context;
 1591                         u_int8_t digest[16];
 1592 
 1593                         MD5Init(&context);
 1594 
 1595                         MD5Update(&context,
 1596                                   (unsigned char *)&path->device->inq_data,
 1597                                   sizeof(struct scsi_inquiry_data));
 1598 
 1599                         if (have_serialnum)
 1600                                 MD5Update(&context, serial_buf->serial_num,
 1601                                           serial_buf->length);
 1602 
 1603                         MD5Final(digest, &context);
 1604                         if (bcmp(softc->digest, digest, 16) == 0)
 1605                                 changed = 0;
 1606 
 1607                         /*
 1608                          * XXX Do we need to do a TUR in order to ensure
 1609                          *     that the device really hasn't changed???
 1610                          */
 1611                         if ((changed != 0)
 1612                          && ((softc->flags & PROBE_NO_ANNOUNCE) == 0))
 1613                                 xpt_async(AC_LOST_DEVICE, path, NULL);
 1614                 }
 1615                 if (serial_buf != NULL)
 1616                         free(serial_buf, M_CAMXPT);
 1617 
 1618                 if (changed != 0) {
 1619                         /*
 1620                          * Now that we have all the necessary
 1621                          * information to safely perform transfer
 1622                          * negotiations... Controllers don't perform
 1623                          * any negotiation or tagged queuing until
 1624                          * after the first XPT_SET_TRAN_SETTINGS ccb is
 1625                          * received.  So, on a new device, just retrieve
 1626                          * the user settings, and set them as the current
 1627                          * settings to set the device up.
 1628                          */
 1629                         proberequestdefaultnegotiation(periph);
 1630                         xpt_release_ccb(done_ccb);
 1631 
 1632                         /*
 1633                          * Perform a TUR to allow the controller to
 1634                          * perform any necessary transfer negotiation.
 1635                          */
 1636                         PROBE_SET_ACTION(softc, PROBE_TUR_FOR_NEGOTIATION);
 1637                         xpt_schedule(periph, priority);
 1638                         goto out;
 1639                 }
 1640                 xpt_release_ccb(done_ccb);
 1641                 break;
 1642         }
 1643         case PROBE_TUR_FOR_NEGOTIATION:
 1644         case PROBE_DV_EXIT:
 1645                 if (cam_ccb_status(done_ccb) != CAM_REQ_CMP) {
 1646                         cam_periph_error(done_ccb, 0,
 1647                             SF_NO_PRINT | SF_NO_RECOVERY | SF_NO_RETRY, NULL);
 1648                 }
 1649                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 1650                         /* Don't wedge the queue */
 1651                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 1652                                          /*run_queue*/TRUE);
 1653                 }
 1654                 /*
 1655                  * Do Domain Validation for lun 0 on devices that claim
 1656                  * to support Synchronous Transfer modes.
 1657                  */
 1658                 if (softc->action == PROBE_TUR_FOR_NEGOTIATION
 1659                  && done_ccb->ccb_h.target_lun == 0
 1660                  && (path->device->inq_data.flags & SID_Sync) != 0
 1661                  && (path->device->flags & CAM_DEV_IN_DV) == 0) {
 1662                         CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
 1663                             ("Begin Domain Validation\n"));
 1664                         path->device->flags |= CAM_DEV_IN_DV;
 1665                         xpt_release_ccb(done_ccb);
 1666                         PROBE_SET_ACTION(softc, PROBE_INQUIRY_BASIC_DV1);
 1667                         xpt_schedule(periph, priority);
 1668                         goto out;
 1669                 }
 1670                 if (softc->action == PROBE_DV_EXIT) {
 1671                         CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
 1672                             ("Leave Domain Validation\n"));
 1673                 }
 1674                 if (path->device->flags & CAM_DEV_UNCONFIGURED) {
 1675                         path->device->flags &= ~CAM_DEV_UNCONFIGURED;
 1676                         xpt_acquire_device(path->device);
 1677                 }
 1678                 path->device->flags &=
 1679                     ~(CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
 1680                 if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
 1681                         /* Inform the XPT that a new device has been found */
 1682                         done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 1683                         xpt_action(done_ccb);
 1684                         xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
 1685                                   done_ccb);
 1686                 }
 1687                 PROBE_SET_ACTION(softc, PROBE_DONE);
 1688                 xpt_release_ccb(done_ccb);
 1689                 break;
 1690         case PROBE_INQUIRY_BASIC_DV1:
 1691         case PROBE_INQUIRY_BASIC_DV2:
 1692         {
 1693                 struct scsi_inquiry_data *nbuf;
 1694                 struct ccb_scsiio *csio;
 1695 
 1696                 if (cam_ccb_status(done_ccb) != CAM_REQ_CMP) {
 1697                         cam_periph_error(done_ccb, 0,
 1698                             SF_NO_PRINT | SF_NO_RECOVERY | SF_NO_RETRY, NULL);
 1699                 }
 1700                 if ((done_ccb->ccb_h.status & CAM_DEV_QFRZN) != 0) {
 1701                         /* Don't wedge the queue */
 1702                         xpt_release_devq(done_ccb->ccb_h.path, /*count*/1,
 1703                                          /*run_queue*/TRUE);
 1704                 }
 1705                 csio = &done_ccb->csio;
 1706                 nbuf = (struct scsi_inquiry_data *)csio->data_ptr;
 1707                 if (bcmp(nbuf, &path->device->inq_data, SHORT_INQUIRY_LENGTH)) {
 1708                         xpt_print(path,
 1709                             "inquiry data fails comparison at DV%d step\n",
 1710                             softc->action == PROBE_INQUIRY_BASIC_DV1 ? 1 : 2);
 1711                         if (proberequestbackoff(periph, path->device)) {
 1712                                 path->device->flags &= ~CAM_DEV_IN_DV;
 1713                                 PROBE_SET_ACTION(softc, PROBE_TUR_FOR_NEGOTIATION);
 1714                         } else {
 1715                                 /* give up */
 1716                                 PROBE_SET_ACTION(softc, PROBE_DV_EXIT);
 1717                         }
 1718                         free(nbuf, M_CAMXPT);
 1719                         xpt_release_ccb(done_ccb);
 1720                         xpt_schedule(periph, priority);
 1721                         goto out;
 1722                 }
 1723                 free(nbuf, M_CAMXPT);
 1724                 if (softc->action == PROBE_INQUIRY_BASIC_DV1) {
 1725                         PROBE_SET_ACTION(softc, PROBE_INQUIRY_BASIC_DV2);
 1726                         xpt_release_ccb(done_ccb);
 1727                         xpt_schedule(periph, priority);
 1728                         goto out;
 1729                 }
 1730                 if (softc->action == PROBE_INQUIRY_BASIC_DV2) {
 1731                         CAM_DEBUG(periph->path, CAM_DEBUG_PROBE,
 1732                             ("Leave Domain Validation Successfully\n"));
 1733                 }
 1734                 if (path->device->flags & CAM_DEV_UNCONFIGURED) {
 1735                         path->device->flags &= ~CAM_DEV_UNCONFIGURED;
 1736                         xpt_acquire_device(path->device);
 1737                 }
 1738                 path->device->flags &=
 1739                     ~(CAM_DEV_IN_DV|CAM_DEV_DV_HIT_BOTTOM);
 1740                 if ((softc->flags & PROBE_NO_ANNOUNCE) == 0) {
 1741                         /* Inform the XPT that a new device has been found */
 1742                         done_ccb->ccb_h.func_code = XPT_GDEV_TYPE;
 1743                         xpt_action(done_ccb);
 1744                         xpt_async(AC_FOUND_DEVICE, done_ccb->ccb_h.path,
 1745                                   done_ccb);
 1746                 }
 1747                 PROBE_SET_ACTION(softc, PROBE_DONE);
 1748                 xpt_release_ccb(done_ccb);
 1749                 break;
 1750         }
 1751         default:
 1752                 panic("probedone: invalid action state 0x%x\n", softc->action);
 1753         }
 1754         done_ccb = (union ccb *)TAILQ_FIRST(&softc->request_ccbs);
 1755         TAILQ_REMOVE(&softc->request_ccbs, &done_ccb->ccb_h, periph_links.tqe);
 1756         done_ccb->ccb_h.status = CAM_REQ_CMP;
 1757         xpt_done(done_ccb);
 1758         if (TAILQ_FIRST(&softc->request_ccbs) == NULL) {
 1759                 CAM_DEBUG(periph->path, CAM_DEBUG_PROBE, ("Probe completed\n"));
 1760                 /* Drop freeze taken due to CAM_DEV_QFREEZE flag set. */
 1761                 cam_release_devq(path, 0, 0, 0, FALSE);
 1762                 cam_periph_release_locked(periph);
 1763                 cam_periph_invalidate(periph);
 1764                 cam_periph_release_locked(periph);
 1765         } else {
 1766                 probeschedule(periph);
 1767                 goto out;
 1768         }
 1769 }
 1770 
 1771 static void
 1772 probe_purge_old(struct cam_path *path, struct scsi_report_luns_data *new,
 1773     probe_flags flags)
 1774 {
 1775         struct cam_path *tp;
 1776         struct scsi_report_luns_data *old;
 1777         u_int idx1, idx2, nlun_old, nlun_new;
 1778         lun_id_t this_lun;
 1779         u_int8_t *ol, *nl;
 1780 
 1781         if (path->target == NULL) {
 1782                 return;
 1783         }
 1784         mtx_lock(&path->target->luns_mtx);
 1785         old = path->target->luns;
 1786         path->target->luns = new;
 1787         mtx_unlock(&path->target->luns_mtx);
 1788         if (old == NULL)
 1789                 return;
 1790         nlun_old = scsi_4btoul(old->length) / 8;
 1791         nlun_new = scsi_4btoul(new->length) / 8;
 1792 
 1793         /*
 1794          * We are not going to assume sorted lists. Deal.
 1795          */
 1796         for (idx1 = 0; idx1 < nlun_old; idx1++) {
 1797                 ol = old->luns[idx1].lundata;
 1798                 for (idx2 = 0; idx2 < nlun_new; idx2++) {
 1799                         nl = new->luns[idx2].lundata;
 1800                         if (memcmp(nl, ol, 8) == 0) {
 1801                                 break;
 1802                         }
 1803                 }
 1804                 if (idx2 < nlun_new) {
 1805                         continue;
 1806                 }
 1807                 /*
 1808                  * An 'old' item not in the 'new' list.
 1809                  * Nuke it. Except that if it is lun 0,
 1810                  * that would be what the probe state
 1811                  * machine is currently working on,
 1812                  * so we won't do that.
 1813                  */
 1814                 CAM_GET_LUN(old, idx1, this_lun);
 1815                 if (this_lun == 0) {
 1816                         continue;
 1817                 }
 1818 
 1819                 /*
 1820                  * We also cannot nuke it if it is
 1821                  * not in a lun format we understand
 1822                  * and replace the LUN with a "simple" LUN
 1823                  * if that is all the HBA supports.
 1824                  */
 1825                 if (!(flags & PROBE_EXTLUN)) {
 1826                         if (!CAM_CAN_GET_SIMPLE_LUN(old, idx1))
 1827                                 continue;
 1828                         CAM_GET_SIMPLE_LUN(old, idx1, this_lun);
 1829                 }
 1830                 if (!CAM_LUN_ONLY_32BITS(old, idx1))
 1831                         continue;
 1832 
 1833                 if (xpt_create_path(&tp, NULL, xpt_path_path_id(path),
 1834                     xpt_path_target_id(path), this_lun) == CAM_REQ_CMP) {
 1835                         xpt_async(AC_LOST_DEVICE, tp, NULL);
 1836                         xpt_free_path(tp);
 1837                 }
 1838         }
 1839         free(old, M_CAMXPT);
 1840 }
 1841 
 1842 static void
 1843 probecleanup(struct cam_periph *periph)
 1844 {
 1845         free(periph->softc, M_CAMXPT);
 1846 }
 1847 
 1848 static void
 1849 scsi_find_quirk(struct cam_ed *device)
 1850 {
 1851         struct scsi_quirk_entry *quirk;
 1852         caddr_t match;
 1853 
 1854         match = cam_quirkmatch((caddr_t)&device->inq_data,
 1855                                (caddr_t)scsi_quirk_table,
 1856                                sizeof(scsi_quirk_table) /
 1857                                sizeof(*scsi_quirk_table),
 1858                                sizeof(*scsi_quirk_table), scsi_inquiry_match);
 1859 
 1860         if (match == NULL)
 1861                 panic("xpt_find_quirk: device didn't match wildcard entry!!");
 1862 
 1863         quirk = (struct scsi_quirk_entry *)match;
 1864         device->quirk = quirk;
 1865         device->mintags = quirk->mintags;
 1866         device->maxtags = quirk->maxtags;
 1867 }
 1868 
 1869 static int
 1870 sysctl_cam_search_luns(SYSCTL_HANDLER_ARGS)
 1871 {
 1872         int error, val;
 1873 
 1874         val = cam_srch_hi;
 1875         error = sysctl_handle_int(oidp, &val, 0, req);
 1876         if (error != 0 || req->newptr == NULL)
 1877                 return (error);
 1878         if (val == 0 || val == 1) {
 1879                 cam_srch_hi = val;
 1880                 return (0);
 1881         } else {
 1882                 return (EINVAL);
 1883         }
 1884 }
 1885 
 1886 typedef struct {
 1887         union   ccb *request_ccb;
 1888         struct  ccb_pathinq *cpi;
 1889         int     counter;
 1890         int     lunindex[0];
 1891 } scsi_scan_bus_info;
 1892 
 1893 /*
 1894  * To start a scan, request_ccb is an XPT_SCAN_BUS ccb.
 1895  * As the scan progresses, scsi_scan_bus is used as the
 1896  * callback on completion function.
 1897  */
 1898 static void
 1899 scsi_scan_bus(struct cam_periph *periph, union ccb *request_ccb)
 1900 {
 1901         struct mtx *mtx;
 1902 
 1903         CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
 1904                   ("scsi_scan_bus\n"));
 1905         switch (request_ccb->ccb_h.func_code) {
 1906         case XPT_SCAN_BUS:
 1907         case XPT_SCAN_TGT:
 1908         {
 1909                 scsi_scan_bus_info *scan_info;
 1910                 union   ccb *work_ccb, *reset_ccb;
 1911                 struct  cam_path *path;
 1912                 u_int   i;
 1913                 u_int   low_target, max_target;
 1914                 u_int   initiator_id;
 1915 
 1916                 /* Find out the characteristics of the bus */
 1917                 work_ccb = xpt_alloc_ccb_nowait();
 1918                 if (work_ccb == NULL) {
 1919                         request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 1920                         xpt_done(request_ccb);
 1921                         return;
 1922                 }
 1923                 xpt_setup_ccb(&work_ccb->ccb_h, request_ccb->ccb_h.path,
 1924                               request_ccb->ccb_h.pinfo.priority);
 1925                 work_ccb->ccb_h.func_code = XPT_PATH_INQ;
 1926                 xpt_action(work_ccb);
 1927                 if (work_ccb->ccb_h.status != CAM_REQ_CMP) {
 1928                         request_ccb->ccb_h.status = work_ccb->ccb_h.status;
 1929                         xpt_free_ccb(work_ccb);
 1930                         xpt_done(request_ccb);
 1931                         return;
 1932                 }
 1933 
 1934                 if ((work_ccb->cpi.hba_misc & PIM_NOINITIATOR) != 0) {
 1935                         /*
 1936                          * Can't scan the bus on an adapter that
 1937                          * cannot perform the initiator role.
 1938                          */
 1939                         request_ccb->ccb_h.status = CAM_REQ_CMP;
 1940                         xpt_free_ccb(work_ccb);
 1941                         xpt_done(request_ccb);
 1942                         return;
 1943                 }
 1944 
 1945                 /* We may need to reset bus first, if we haven't done it yet. */
 1946                 if ((work_ccb->cpi.hba_inquiry &
 1947                     (PI_WIDE_32|PI_WIDE_16|PI_SDTR_ABLE)) &&
 1948                     !(work_ccb->cpi.hba_misc & PIM_NOBUSRESET) &&
 1949                     !timevalisset(&request_ccb->ccb_h.path->bus->last_reset) &&
 1950                     (reset_ccb = xpt_alloc_ccb_nowait()) != NULL) {
 1951                         xpt_setup_ccb(&reset_ccb->ccb_h, request_ccb->ccb_h.path,
 1952                               CAM_PRIORITY_NONE);
 1953                         reset_ccb->ccb_h.func_code = XPT_RESET_BUS;
 1954                         xpt_action(reset_ccb);
 1955                         if (reset_ccb->ccb_h.status != CAM_REQ_CMP) {
 1956                                 request_ccb->ccb_h.status = reset_ccb->ccb_h.status;
 1957                                 xpt_free_ccb(reset_ccb);
 1958                                 xpt_free_ccb(work_ccb);
 1959                                 xpt_done(request_ccb);
 1960                                 return;
 1961                         }
 1962                         xpt_free_ccb(reset_ccb);
 1963                 }
 1964 
 1965                 /* Save some state for use while we probe for devices */
 1966                 scan_info = (scsi_scan_bus_info *) malloc(sizeof(scsi_scan_bus_info) +
 1967                     (work_ccb->cpi.max_target * sizeof (u_int)), M_CAMXPT, M_ZERO|M_NOWAIT);
 1968                 if (scan_info == NULL) {
 1969                         request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 1970                         xpt_free_ccb(work_ccb);
 1971                         xpt_done(request_ccb);
 1972                         return;
 1973                 }
 1974                 CAM_DEBUG(request_ccb->ccb_h.path, CAM_DEBUG_TRACE,
 1975                    ("SCAN start for %p\n", scan_info));
 1976                 scan_info->request_ccb = request_ccb;
 1977                 scan_info->cpi = &work_ccb->cpi;
 1978 
 1979                 /* Cache on our stack so we can work asynchronously */
 1980                 max_target = scan_info->cpi->max_target;
 1981                 low_target = 0;
 1982                 initiator_id = scan_info->cpi->initiator_id;
 1983 
 1984 
 1985                 /*
 1986                  * We can scan all targets in parallel, or do it sequentially.
 1987                  */
 1988 
 1989                 if (request_ccb->ccb_h.func_code == XPT_SCAN_TGT) {
 1990                         max_target = low_target = request_ccb->ccb_h.target_id;
 1991                         scan_info->counter = 0;
 1992                 } else if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
 1993                         max_target = 0;
 1994                         scan_info->counter = 0;
 1995                 } else {
 1996                         scan_info->counter = scan_info->cpi->max_target + 1;
 1997                         if (scan_info->cpi->initiator_id < scan_info->counter) {
 1998                                 scan_info->counter--;
 1999                         }
 2000                 }
 2001                 mtx = xpt_path_mtx(scan_info->request_ccb->ccb_h.path);
 2002                 mtx_unlock(mtx);
 2003 
 2004                 for (i = low_target; i <= max_target; i++) {
 2005                         cam_status status;
 2006                         if (i == initiator_id)
 2007                                 continue;
 2008 
 2009                         status = xpt_create_path(&path, NULL,
 2010                                                  request_ccb->ccb_h.path_id,
 2011                                                  i, 0);
 2012                         if (status != CAM_REQ_CMP) {
 2013                                 printf("scsi_scan_bus: xpt_create_path failed"
 2014                                        " with status %#x, bus scan halted\n",
 2015                                        status);
 2016                                 free(scan_info, M_CAMXPT);
 2017                                 request_ccb->ccb_h.status = status;
 2018                                 xpt_free_ccb(work_ccb);
 2019                                 xpt_done(request_ccb);
 2020                                 break;
 2021                         }
 2022                         work_ccb = xpt_alloc_ccb_nowait();
 2023                         if (work_ccb == NULL) {
 2024                                 xpt_free_ccb((union ccb *)scan_info->cpi);
 2025                                 free(scan_info, M_CAMXPT);
 2026                                 xpt_free_path(path);
 2027                                 request_ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
 2028                                 xpt_done(request_ccb);
 2029                                 break;
 2030                         }
 2031                         xpt_setup_ccb(&work_ccb->ccb_h, path,
 2032                                       request_ccb->ccb_h.pinfo.priority);
 2033                         work_ccb->ccb_h.func_code = XPT_SCAN_LUN;
 2034                         work_ccb->ccb_h.cbfcnp = scsi_scan_bus;
 2035                         work_ccb->ccb_h.flags |= CAM_UNLOCKED;
 2036                         work_ccb->ccb_h.ppriv_ptr0 = scan_info;
 2037                         work_ccb->crcn.flags = request_ccb->crcn.flags;
 2038                         xpt_action(work_ccb);
 2039                 }
 2040 
 2041                 mtx_lock(mtx);
 2042                 break;
 2043         }
 2044         case XPT_SCAN_LUN:
 2045         {
 2046                 cam_status status;
 2047                 struct cam_path *path, *oldpath;
 2048                 scsi_scan_bus_info *scan_info;
 2049                 struct cam_et *target;
 2050                 struct cam_ed *device, *nextdev;
 2051                 int next_target;
 2052                 path_id_t path_id;
 2053                 target_id_t target_id;
 2054                 lun_id_t lun_id;
 2055 
 2056                 oldpath = request_ccb->ccb_h.path;
 2057 
 2058                 status = cam_ccb_status(request_ccb);
 2059                 scan_info = (scsi_scan_bus_info *)request_ccb->ccb_h.ppriv_ptr0;
 2060                 path_id = request_ccb->ccb_h.path_id;
 2061                 target_id = request_ccb->ccb_h.target_id;
 2062                 lun_id = request_ccb->ccb_h.target_lun;
 2063                 target = request_ccb->ccb_h.path->target;
 2064                 next_target = 1;
 2065 
 2066                 mtx = xpt_path_mtx(scan_info->request_ccb->ccb_h.path);
 2067                 mtx_lock(mtx);
 2068                 mtx_lock(&target->luns_mtx);
 2069                 if (target->luns) {
 2070                         lun_id_t first;
 2071                         u_int nluns = scsi_4btoul(target->luns->length) / 8;
 2072 
 2073                         /*
 2074                          * Make sure we skip over lun 0 if it's the first member
 2075                          * of the list as we've actually just finished probing
 2076                          * it.
 2077                          */
 2078                         CAM_GET_LUN(target->luns, 0, first);
 2079                         if (first == 0 && scan_info->lunindex[target_id] == 0) {
 2080                                 scan_info->lunindex[target_id]++;
 2081                         } 
 2082 
 2083                         /*
 2084                          * Skip any LUNs that the HBA can't deal with.
 2085                          */
 2086                         while (scan_info->lunindex[target_id] < nluns) {
 2087                                 if (scan_info->cpi->hba_misc & PIM_EXTLUNS) {
 2088                                         CAM_GET_LUN(target->luns,
 2089                                             scan_info->lunindex[target_id],
 2090                                             lun_id);
 2091                                         break;
 2092                                 }
 2093 
 2094                                 /* XXX print warning? */
 2095                                 if (!CAM_LUN_ONLY_32BITS(target->luns,
 2096                                     scan_info->lunindex[target_id]))
 2097                                         continue;
 2098                                 if (CAM_CAN_GET_SIMPLE_LUN(target->luns,
 2099                                     scan_info->lunindex[target_id])) {
 2100                                         CAM_GET_SIMPLE_LUN(target->luns,
 2101                                             scan_info->lunindex[target_id],
 2102                                             lun_id);
 2103                                         break;
 2104                                 }
 2105                                         
 2106                                 scan_info->lunindex[target_id]++;
 2107                         }
 2108 
 2109                         if (scan_info->lunindex[target_id] < nluns) {
 2110                                 mtx_unlock(&target->luns_mtx);
 2111                                 next_target = 0;
 2112                                 CAM_DEBUG(request_ccb->ccb_h.path,
 2113                                     CAM_DEBUG_PROBE,
 2114                                    ("next lun to try at index %u is %jx\n",
 2115                                    scan_info->lunindex[target_id],
 2116                                    (uintmax_t)lun_id));
 2117                                 scan_info->lunindex[target_id]++;
 2118                         } else {
 2119                                 mtx_unlock(&target->luns_mtx);
 2120                                 /* We're done with scanning all luns. */
 2121                         }
 2122                 } else {
 2123                         mtx_unlock(&target->luns_mtx);
 2124                         device = request_ccb->ccb_h.path->device;
 2125                         /* Continue sequential LUN scan if: */
 2126                         /*  -- we have more LUNs that need recheck */
 2127                         mtx_lock(&target->bus->eb_mtx);
 2128                         nextdev = device;
 2129                         while ((nextdev = TAILQ_NEXT(nextdev, links)) != NULL)
 2130                                 if ((nextdev->flags & CAM_DEV_UNCONFIGURED) == 0)
 2131                                         break;
 2132                         mtx_unlock(&target->bus->eb_mtx);
 2133                         if (nextdev != NULL) {
 2134                                 next_target = 0;
 2135                         /*  -- stop if CAM_QUIRK_NOLUNS is set. */
 2136                         } else if (SCSI_QUIRK(device)->quirks & CAM_QUIRK_NOLUNS) {
 2137                                 next_target = 1;
 2138                         /*  -- this LUN is connected and its SCSI version
 2139                          *     allows more LUNs. */
 2140                         } else if ((device->flags & CAM_DEV_UNCONFIGURED) == 0) {
 2141                                 if (lun_id < (CAM_SCSI2_MAXLUN-1) ||
 2142                                     CAN_SRCH_HI_DENSE(device))
 2143                                         next_target = 0;
 2144                         /*  -- this LUN is disconnected, its SCSI version
 2145                          *     allows more LUNs and we guess they may be. */
 2146                         } else if ((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0) {
 2147                                 if (lun_id < (CAM_SCSI2_MAXLUN-1) ||
 2148                                     CAN_SRCH_HI_SPARSE(device))
 2149                                         next_target = 0;
 2150                         }
 2151                         if (next_target == 0) {
 2152                                 lun_id++;
 2153                                 if (lun_id > scan_info->cpi->max_lun)
 2154                                         next_target = 1;
 2155                         }
 2156                 }
 2157 
 2158                 /*
 2159                  * Check to see if we scan any further luns.
 2160                  */
 2161                 if (next_target) {
 2162                         int done;
 2163 
 2164                         /*
 2165                          * Free the current request path- we're done with it.
 2166                          */
 2167                         xpt_free_path(oldpath);
 2168  hop_again:
 2169                         done = 0;
 2170                         if (scan_info->request_ccb->ccb_h.func_code == XPT_SCAN_TGT) {
 2171                                 done = 1;
 2172                         } else if (scan_info->cpi->hba_misc & PIM_SEQSCAN) {
 2173                                 scan_info->counter++;
 2174                                 if (scan_info->counter ==
 2175                                     scan_info->cpi->initiator_id) {
 2176                                         scan_info->counter++;
 2177                                 }
 2178                                 if (scan_info->counter >=
 2179                                     scan_info->cpi->max_target+1) {
 2180                                         done = 1;
 2181                                 }
 2182                         } else {
 2183                                 scan_info->counter--;
 2184                                 if (scan_info->counter == 0) {
 2185                                         done = 1;
 2186                                 }
 2187                         }
 2188                         if (done) {
 2189                                 mtx_unlock(mtx);
 2190                                 xpt_free_ccb(request_ccb);
 2191                                 xpt_free_ccb((union ccb *)scan_info->cpi);
 2192                                 request_ccb = scan_info->request_ccb;
 2193                                 CAM_DEBUG(request_ccb->ccb_h.path,
 2194                                     CAM_DEBUG_TRACE,
 2195                                    ("SCAN done for %p\n", scan_info));
 2196                                 free(scan_info, M_CAMXPT);
 2197                                 request_ccb->ccb_h.status = CAM_REQ_CMP;
 2198                                 xpt_done(request_ccb);
 2199                                 break;
 2200                         }
 2201 
 2202                         if ((scan_info->cpi->hba_misc & PIM_SEQSCAN) == 0) {
 2203                                 mtx_unlock(mtx);
 2204                                 xpt_free_ccb(request_ccb);
 2205                                 break;
 2206                         }
 2207                         status = xpt_create_path(&path, NULL,
 2208                             scan_info->request_ccb->ccb_h.path_id,
 2209                             scan_info->counter, 0);
 2210                         if (status != CAM_REQ_CMP) {
 2211                                 mtx_unlock(mtx);
 2212                                 printf("scsi_scan_bus: xpt_create_path failed"
 2213                                     " with status %#x, bus scan halted\n",
 2214                                     status);
 2215                                 xpt_free_ccb(request_ccb);
 2216                                 xpt_free_ccb((union ccb *)scan_info->cpi);
 2217                                 request_ccb = scan_info->request_ccb;
 2218                                 free(scan_info, M_CAMXPT);
 2219                                 request_ccb->ccb_h.status = status;
 2220                                 xpt_done(request_ccb);
 2221                                 break;
 2222                         }
 2223                         xpt_setup_ccb(&request_ccb->ccb_h, path,
 2224                             request_ccb->ccb_h.pinfo.priority);
 2225                         request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
 2226                         request_ccb->ccb_h.cbfcnp = scsi_scan_bus;
 2227                         request_ccb->ccb_h.flags |= CAM_UNLOCKED;
 2228                         request_ccb->ccb_h.ppriv_ptr0 = scan_info;
 2229                         request_ccb->crcn.flags =
 2230                             scan_info->request_ccb->crcn.flags;
 2231                 } else {
 2232                         status = xpt_create_path(&path, NULL,
 2233                                                  path_id, target_id, lun_id);
 2234                         /*
 2235                          * Free the old request path- we're done with it. We
 2236                          * do this *after* creating the new path so that
 2237                          * we don't remove a target that has our lun list
 2238                          * in the case that lun 0 is not present.
 2239                          */
 2240                         xpt_free_path(oldpath);
 2241                         if (status != CAM_REQ_CMP) {
 2242                                 printf("scsi_scan_bus: xpt_create_path failed "
 2243                                        "with status %#x, halting LUN scan\n",
 2244                                        status);
 2245                                 goto hop_again;
 2246                         }
 2247                         xpt_setup_ccb(&request_ccb->ccb_h, path,
 2248                                       request_ccb->ccb_h.pinfo.priority);
 2249                         request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
 2250                         request_ccb->ccb_h.cbfcnp = scsi_scan_bus;
 2251                         request_ccb->ccb_h.flags |= CAM_UNLOCKED;
 2252                         request_ccb->ccb_h.ppriv_ptr0 = scan_info;
 2253                         request_ccb->crcn.flags =
 2254                                 scan_info->request_ccb->crcn.flags;
 2255                 }
 2256                 mtx_unlock(mtx);
 2257                 xpt_action(request_ccb);
 2258                 break;
 2259         }
 2260         default:
 2261                 break;
 2262         }
 2263 }
 2264 
 2265 static void
 2266 scsi_scan_lun(struct cam_periph *periph, struct cam_path *path,
 2267              cam_flags flags, union ccb *request_ccb)
 2268 {
 2269         struct ccb_pathinq cpi;
 2270         cam_status status;
 2271         struct cam_path *new_path;
 2272         struct cam_periph *old_periph;
 2273         int lock;
 2274 
 2275         CAM_DEBUG(path, CAM_DEBUG_TRACE, ("scsi_scan_lun\n"));
 2276 
 2277         xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE);
 2278         cpi.ccb_h.func_code = XPT_PATH_INQ;
 2279         xpt_action((union ccb *)&cpi);
 2280 
 2281         if (cpi.ccb_h.status != CAM_REQ_CMP) {
 2282                 if (request_ccb != NULL) {
 2283                         request_ccb->ccb_h.status = cpi.ccb_h.status;
 2284                         xpt_done(request_ccb);
 2285                 }
 2286                 return;
 2287         }
 2288 
 2289         if ((cpi.hba_misc & PIM_NOINITIATOR) != 0) {
 2290                 /*
 2291                  * Can't scan the bus on an adapter that
 2292                  * cannot perform the initiator role.
 2293                  */
 2294                 if (request_ccb != NULL) {
 2295                         request_ccb->ccb_h.status = CAM_REQ_CMP;
 2296                         xpt_done(request_ccb);
 2297                 }
 2298                 return;
 2299         }
 2300 
 2301         if (request_ccb == NULL) {
 2302                 request_ccb = xpt_alloc_ccb_nowait();
 2303                 if (request_ccb == NULL) {
 2304                         xpt_print(path, "scsi_scan_lun: can't allocate CCB, "
 2305                             "can't continue\n");
 2306                         return;
 2307                 }
 2308                 status = xpt_create_path(&new_path, NULL,
 2309                                           path->bus->path_id,
 2310                                           path->target->target_id,
 2311                                           path->device->lun_id);
 2312                 if (status != CAM_REQ_CMP) {
 2313                         xpt_print(path, "scsi_scan_lun: can't create path, "
 2314                             "can't continue\n");
 2315                         xpt_free_ccb(request_ccb);
 2316                         return;
 2317                 }
 2318                 xpt_setup_ccb(&request_ccb->ccb_h, new_path, CAM_PRIORITY_XPT);
 2319                 request_ccb->ccb_h.cbfcnp = xptscandone;
 2320                 request_ccb->ccb_h.func_code = XPT_SCAN_LUN;
 2321                 request_ccb->ccb_h.flags |= CAM_UNLOCKED;
 2322                 request_ccb->crcn.flags = flags;
 2323         }
 2324 
 2325         lock = (xpt_path_owned(path) == 0);
 2326         if (lock)
 2327                 xpt_path_lock(path);
 2328         if ((old_periph = cam_periph_find(path, "probe")) != NULL) {
 2329                 if ((old_periph->flags & CAM_PERIPH_INVALID) == 0) {
 2330                         probe_softc *softc;
 2331 
 2332                         softc = (probe_softc *)old_periph->softc;
 2333                         TAILQ_INSERT_TAIL(&softc->request_ccbs,
 2334                             &request_ccb->ccb_h, periph_links.tqe);
 2335                 } else {
 2336                         request_ccb->ccb_h.status = CAM_REQ_CMP_ERR;
 2337                         xpt_done(request_ccb);
 2338                 }
 2339         } else {
 2340                 status = cam_periph_alloc(proberegister, NULL, probecleanup,
 2341                                           probestart, "probe",
 2342                                           CAM_PERIPH_BIO,
 2343                                           request_ccb->ccb_h.path, NULL, 0,
 2344                                           request_ccb);
 2345 
 2346                 if (status != CAM_REQ_CMP) {
 2347                         xpt_print(path, "scsi_scan_lun: cam_alloc_periph "
 2348                             "returned an error, can't continue probe\n");
 2349                         request_ccb->ccb_h.status = status;
 2350                         xpt_done(request_ccb);
 2351                 }
 2352         }
 2353         if (lock)
 2354                 xpt_path_unlock(path);
 2355 }
 2356 
 2357 static void
 2358 xptscandone(struct cam_periph *periph, union ccb *done_ccb)
 2359 {
 2360 
 2361         xpt_free_path(done_ccb->ccb_h.path);
 2362         xpt_free_ccb(done_ccb);
 2363 }
 2364 
 2365 static struct cam_ed *
 2366 scsi_alloc_device(struct cam_eb *bus, struct cam_et *target, lun_id_t lun_id)
 2367 {
 2368         struct scsi_quirk_entry *quirk;
 2369         struct cam_ed *device;
 2370 
 2371         device = xpt_alloc_device(bus, target, lun_id);
 2372         if (device == NULL)
 2373                 return (NULL);
 2374 
 2375         /*
 2376          * Take the default quirk entry until we have inquiry
 2377          * data and can determine a better quirk to use.
 2378          */
 2379         quirk = &scsi_quirk_table[scsi_quirk_table_size - 1];
 2380         device->quirk = (void *)quirk;
 2381         device->mintags = quirk->mintags;
 2382         device->maxtags = quirk->maxtags;
 2383         bzero(&device->inq_data, sizeof(device->inq_data));
 2384         device->inq_flags = 0;
 2385         device->queue_flags = 0;
 2386         device->serial_num = NULL;
 2387         device->serial_num_len = 0;
 2388         device->device_id = NULL;
 2389         device->device_id_len = 0;
 2390         device->supported_vpds = NULL;
 2391         device->supported_vpds_len = 0;
 2392         return (device);
 2393 }
 2394 
 2395 static void
 2396 scsi_devise_transport(struct cam_path *path)
 2397 {
 2398         struct ccb_pathinq cpi;
 2399         struct ccb_trans_settings cts;
 2400         struct scsi_inquiry_data *inq_buf;
 2401 
 2402         /* Get transport information from the SIM */
 2403         xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE);
 2404         cpi.ccb_h.func_code = XPT_PATH_INQ;
 2405         xpt_action((union ccb *)&cpi);
 2406 
 2407         inq_buf = NULL;
 2408         if ((path->device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0)
 2409                 inq_buf = &path->device->inq_data;
 2410         path->device->protocol = PROTO_SCSI;
 2411         path->device->protocol_version =
 2412             inq_buf != NULL ? SID_ANSI_REV(inq_buf) : cpi.protocol_version;
 2413         path->device->transport = cpi.transport;
 2414         path->device->transport_version = cpi.transport_version;
 2415 
 2416         /*
 2417          * Any device not using SPI3 features should
 2418          * be considered SPI2 or lower.
 2419          */
 2420         if (inq_buf != NULL) {
 2421                 if (path->device->transport == XPORT_SPI
 2422                  && (inq_buf->spi3data & SID_SPI_MASK) == 0
 2423                  && path->device->transport_version > 2)
 2424                         path->device->transport_version = 2;
 2425         } else {
 2426                 struct cam_ed* otherdev;
 2427 
 2428                 for (otherdev = TAILQ_FIRST(&path->target->ed_entries);
 2429                      otherdev != NULL;
 2430                      otherdev = TAILQ_NEXT(otherdev, links)) {
 2431                         if (otherdev != path->device)
 2432                                 break;
 2433                 }
 2434 
 2435                 if (otherdev != NULL) {
 2436                         /*
 2437                          * Initially assume the same versioning as
 2438                          * prior luns for this target.
 2439                          */
 2440                         path->device->protocol_version =
 2441                             otherdev->protocol_version;
 2442                         path->device->transport_version =
 2443                             otherdev->transport_version;
 2444                 } else {
 2445                         /* Until we know better, opt for safety */
 2446                         path->device->protocol_version = 2;
 2447                         if (path->device->transport == XPORT_SPI)
 2448                                 path->device->transport_version = 2;
 2449                         else
 2450                                 path->device->transport_version = 0;
 2451                 }
 2452         }
 2453 
 2454         /*
 2455          * XXX
 2456          * For a device compliant with SPC-2 we should be able
 2457          * to determine the transport version supported by
 2458          * scrutinizing the version descriptors in the
 2459          * inquiry buffer.
 2460          */
 2461 
 2462         /* Tell the controller what we think */
 2463         xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
 2464         cts.ccb_h.func_code = XPT_SET_TRAN_SETTINGS;
 2465         cts.type = CTS_TYPE_CURRENT_SETTINGS;
 2466         cts.transport = path->device->transport;
 2467         cts.transport_version = path->device->transport_version;
 2468         cts.protocol = path->device->protocol;
 2469         cts.protocol_version = path->device->protocol_version;
 2470         cts.proto_specific.valid = 0;
 2471         cts.xport_specific.valid = 0;
 2472         xpt_action((union ccb *)&cts);
 2473 }
 2474 
 2475 static void
 2476 scsi_dev_advinfo(union ccb *start_ccb)
 2477 {
 2478         struct cam_ed *device;
 2479         struct ccb_dev_advinfo *cdai;
 2480         off_t amt;
 2481 
 2482         start_ccb->ccb_h.status = CAM_REQ_INVALID;
 2483         device = start_ccb->ccb_h.path->device;
 2484         cdai = &start_ccb->cdai;
 2485         switch(cdai->buftype) {
 2486         case CDAI_TYPE_SCSI_DEVID:
 2487                 if (cdai->flags & CDAI_FLAG_STORE)
 2488                         return;
 2489                 cdai->provsiz = device->device_id_len;
 2490                 if (device->device_id_len == 0)
 2491                         break;
 2492                 amt = device->device_id_len;
 2493                 if (cdai->provsiz > cdai->bufsiz)
 2494                         amt = cdai->bufsiz;
 2495                 memcpy(cdai->buf, device->device_id, amt);
 2496                 break;
 2497         case CDAI_TYPE_SERIAL_NUM:
 2498                 if (cdai->flags & CDAI_FLAG_STORE)
 2499                         return;
 2500                 cdai->provsiz = device->serial_num_len;
 2501                 if (device->serial_num_len == 0)
 2502                         break;
 2503                 amt = device->serial_num_len;
 2504                 if (cdai->provsiz > cdai->bufsiz)
 2505                         amt = cdai->bufsiz;
 2506                 memcpy(cdai->buf, device->serial_num, amt);
 2507                 break;
 2508         case CDAI_TYPE_PHYS_PATH:
 2509                 if (cdai->flags & CDAI_FLAG_STORE) {
 2510                         if (device->physpath != NULL) {
 2511                                 free(device->physpath, M_CAMXPT);
 2512                                 device->physpath = NULL;
 2513                         }
 2514                         device->physpath_len = cdai->bufsiz;
 2515                         /* Clear existing buffer if zero length */
 2516                         if (cdai->bufsiz == 0)
 2517                                 break;
 2518                         device->physpath = malloc(cdai->bufsiz, M_CAMXPT, M_NOWAIT);
 2519                         if (device->physpath == NULL) {
 2520                                 start_ccb->ccb_h.status = CAM_REQ_ABORTED;
 2521                                 return;
 2522                         }
 2523                         memcpy(device->physpath, cdai->buf, cdai->bufsiz);
 2524                 } else {
 2525                         cdai->provsiz = device->physpath_len;
 2526                         if (device->physpath_len == 0)
 2527                                 break;
 2528                         amt = device->physpath_len;
 2529                         if (cdai->provsiz > cdai->bufsiz)
 2530                                 amt = cdai->bufsiz;
 2531                         memcpy(cdai->buf, device->physpath, amt);
 2532                 }
 2533                 break;
 2534         case CDAI_TYPE_RCAPLONG:
 2535                 if (cdai->flags & CDAI_FLAG_STORE) {
 2536                         if (device->rcap_buf != NULL) {
 2537                                 free(device->rcap_buf, M_CAMXPT);
 2538                                 device->rcap_buf = NULL;
 2539                         }
 2540 
 2541                         device->rcap_len = cdai->bufsiz;
 2542                         /* Clear existing buffer if zero length */
 2543                         if (cdai->bufsiz == 0)
 2544                                 break;
 2545 
 2546                         device->rcap_buf = malloc(cdai->bufsiz, M_CAMXPT,
 2547                                                   M_NOWAIT);
 2548                         if (device->rcap_buf == NULL) {
 2549                                 start_ccb->ccb_h.status = CAM_REQ_ABORTED;
 2550                                 return;
 2551                         }
 2552 
 2553                         memcpy(device->rcap_buf, cdai->buf, cdai->bufsiz);
 2554                 } else {
 2555                         cdai->provsiz = device->rcap_len;
 2556                         if (device->rcap_len == 0)
 2557                                 break;
 2558                         amt = device->rcap_len;
 2559                         if (cdai->provsiz > cdai->bufsiz)
 2560                                 amt = cdai->bufsiz;
 2561                         memcpy(cdai->buf, device->rcap_buf, amt);
 2562                 }
 2563                 break;
 2564         case CDAI_TYPE_EXT_INQ:
 2565                 /*
 2566                  * We fetch extended inquiry data during probe, if
 2567                  * available.  We don't allow changing it.
 2568                  */
 2569                 if (cdai->flags & CDAI_FLAG_STORE) 
 2570                         return;
 2571                 cdai->provsiz = device->ext_inq_len;
 2572                 if (device->ext_inq_len == 0)
 2573                         break;
 2574                 amt = device->ext_inq_len;
 2575                 if (cdai->provsiz > cdai->bufsiz)
 2576                         amt = cdai->bufsiz;
 2577                 memcpy(cdai->buf, device->ext_inq, amt);
 2578                 break;
 2579         default:
 2580                 return;
 2581         }
 2582         start_ccb->ccb_h.status = CAM_REQ_CMP;
 2583 
 2584         if (cdai->flags & CDAI_FLAG_STORE) {
 2585                 xpt_async(AC_ADVINFO_CHANGED, start_ccb->ccb_h.path,
 2586                           (void *)(uintptr_t)cdai->buftype);
 2587         }
 2588 }
 2589 
 2590 static void
 2591 scsi_action(union ccb *start_ccb)
 2592 {
 2593 
 2594         switch (start_ccb->ccb_h.func_code) {
 2595         case XPT_SET_TRAN_SETTINGS:
 2596         {
 2597                 scsi_set_transfer_settings(&start_ccb->cts,
 2598                                            start_ccb->ccb_h.path,
 2599                                            /*async_update*/FALSE);
 2600                 break;
 2601         }
 2602         case XPT_SCAN_BUS:
 2603         case XPT_SCAN_TGT:
 2604                 scsi_scan_bus(start_ccb->ccb_h.path->periph, start_ccb);
 2605                 break;
 2606         case XPT_SCAN_LUN:
 2607                 scsi_scan_lun(start_ccb->ccb_h.path->periph,
 2608                               start_ccb->ccb_h.path, start_ccb->crcn.flags,
 2609                               start_ccb);
 2610                 break;
 2611         case XPT_DEV_ADVINFO:
 2612         {
 2613                 scsi_dev_advinfo(start_ccb);
 2614                 break;
 2615         }
 2616         default:
 2617                 xpt_action_default(start_ccb);
 2618                 break;
 2619         }
 2620 }
 2621 
 2622 static void
 2623 scsi_set_transfer_settings(struct ccb_trans_settings *cts, struct cam_path *path,
 2624                            int async_update)
 2625 {
 2626         struct  ccb_pathinq cpi;
 2627         struct  ccb_trans_settings cur_cts;
 2628         struct  ccb_trans_settings_scsi *scsi;
 2629         struct  ccb_trans_settings_scsi *cur_scsi;
 2630         struct  scsi_inquiry_data *inq_data;
 2631         struct  cam_ed *device;
 2632 
 2633         if (path == NULL || (device = path->device) == NULL) {
 2634                 cts->ccb_h.status = CAM_PATH_INVALID;
 2635                 xpt_done((union ccb *)cts);
 2636                 return;
 2637         }
 2638 
 2639         if (cts->protocol == PROTO_UNKNOWN
 2640          || cts->protocol == PROTO_UNSPECIFIED) {
 2641                 cts->protocol = device->protocol;
 2642                 cts->protocol_version = device->protocol_version;
 2643         }
 2644 
 2645         if (cts->protocol_version == PROTO_VERSION_UNKNOWN
 2646          || cts->protocol_version == PROTO_VERSION_UNSPECIFIED)
 2647                 cts->protocol_version = device->protocol_version;
 2648 
 2649         if (cts->protocol != device->protocol) {
 2650                 xpt_print(path, "Uninitialized Protocol %x:%x?\n",
 2651                        cts->protocol, device->protocol);
 2652                 cts->protocol = device->protocol;
 2653         }
 2654 
 2655         if (cts->protocol_version > device->protocol_version) {
 2656                 if (bootverbose) {
 2657                         xpt_print(path, "Down reving Protocol "
 2658                             "Version from %d to %d?\n", cts->protocol_version,
 2659                             device->protocol_version);
 2660                 }
 2661                 cts->protocol_version = device->protocol_version;
 2662         }
 2663 
 2664         if (cts->transport == XPORT_UNKNOWN
 2665          || cts->transport == XPORT_UNSPECIFIED) {
 2666                 cts->transport = device->transport;
 2667                 cts->transport_version = device->transport_version;
 2668         }
 2669 
 2670         if (cts->transport_version == XPORT_VERSION_UNKNOWN
 2671          || cts->transport_version == XPORT_VERSION_UNSPECIFIED)
 2672                 cts->transport_version = device->transport_version;
 2673 
 2674         if (cts->transport != device->transport) {
 2675                 xpt_print(path, "Uninitialized Transport %x:%x?\n",
 2676                     cts->transport, device->transport);
 2677                 cts->transport = device->transport;
 2678         }
 2679 
 2680         if (cts->transport_version > device->transport_version) {
 2681                 if (bootverbose) {
 2682                         xpt_print(path, "Down reving Transport "
 2683                             "Version from %d to %d?\n", cts->transport_version,
 2684                             device->transport_version);
 2685                 }
 2686                 cts->transport_version = device->transport_version;
 2687         }
 2688 
 2689         /*
 2690          * Nothing more of interest to do unless
 2691          * this is a device connected via the
 2692          * SCSI protocol.
 2693          */
 2694         if (cts->protocol != PROTO_SCSI) {
 2695                 if (async_update == FALSE)
 2696                         xpt_action_default((union ccb *)cts);
 2697                 return;
 2698         }
 2699 
 2700         inq_data = &device->inq_data;
 2701         scsi = &cts->proto_specific.scsi;
 2702         xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NONE);
 2703         cpi.ccb_h.func_code = XPT_PATH_INQ;
 2704         xpt_action((union ccb *)&cpi);
 2705 
 2706         /* SCSI specific sanity checking */
 2707         if ((cpi.hba_inquiry & PI_TAG_ABLE) == 0
 2708          || (INQ_DATA_TQ_ENABLED(inq_data)) == 0
 2709          || (device->queue_flags & SCP_QUEUE_DQUE) != 0
 2710          || (device->mintags == 0)) {
 2711                 /*
 2712                  * Can't tag on hardware that doesn't support tags,
 2713                  * doesn't have it enabled, or has broken tag support.
 2714                  */
 2715                 scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 2716         }
 2717 
 2718         if (async_update == FALSE) {
 2719                 /*
 2720                  * Perform sanity checking against what the
 2721                  * controller and device can do.
 2722                  */
 2723                 xpt_setup_ccb(&cur_cts.ccb_h, path, CAM_PRIORITY_NONE);
 2724                 cur_cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 2725                 cur_cts.type = cts->type;
 2726                 xpt_action((union ccb *)&cur_cts);
 2727                 if (cam_ccb_status((union ccb *)&cur_cts) != CAM_REQ_CMP) {
 2728                         return;
 2729                 }
 2730                 cur_scsi = &cur_cts.proto_specific.scsi;
 2731                 if ((scsi->valid & CTS_SCSI_VALID_TQ) == 0) {
 2732                         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 2733                         scsi->flags |= cur_scsi->flags & CTS_SCSI_FLAGS_TAG_ENB;
 2734                 }
 2735                 if ((cur_scsi->valid & CTS_SCSI_VALID_TQ) == 0)
 2736                         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 2737         }
 2738 
 2739         /* SPI specific sanity checking */
 2740         if (cts->transport == XPORT_SPI && async_update == FALSE) {
 2741                 u_int spi3caps;
 2742                 struct ccb_trans_settings_spi *spi;
 2743                 struct ccb_trans_settings_spi *cur_spi;
 2744 
 2745                 spi = &cts->xport_specific.spi;
 2746 
 2747                 cur_spi = &cur_cts.xport_specific.spi;
 2748 
 2749                 /* Fill in any gaps in what the user gave us */
 2750                 if ((spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0)
 2751                         spi->sync_period = cur_spi->sync_period;
 2752                 if ((cur_spi->valid & CTS_SPI_VALID_SYNC_RATE) == 0)
 2753                         spi->sync_period = 0;
 2754                 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0)
 2755                         spi->sync_offset = cur_spi->sync_offset;
 2756                 if ((cur_spi->valid & CTS_SPI_VALID_SYNC_OFFSET) == 0)
 2757                         spi->sync_offset = 0;
 2758                 if ((spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0)
 2759                         spi->ppr_options = cur_spi->ppr_options;
 2760                 if ((cur_spi->valid & CTS_SPI_VALID_PPR_OPTIONS) == 0)
 2761                         spi->ppr_options = 0;
 2762                 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) == 0)
 2763                         spi->bus_width = cur_spi->bus_width;
 2764                 if ((cur_spi->valid & CTS_SPI_VALID_BUS_WIDTH) == 0)
 2765                         spi->bus_width = 0;
 2766                 if ((spi->valid & CTS_SPI_VALID_DISC) == 0) {
 2767                         spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
 2768                         spi->flags |= cur_spi->flags & CTS_SPI_FLAGS_DISC_ENB;
 2769                 }
 2770                 if ((cur_spi->valid & CTS_SPI_VALID_DISC) == 0)
 2771                         spi->flags &= ~CTS_SPI_FLAGS_DISC_ENB;
 2772                 if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0
 2773                   && (inq_data->flags & SID_Sync) == 0
 2774                   && cts->type == CTS_TYPE_CURRENT_SETTINGS)
 2775                  || ((cpi.hba_inquiry & PI_SDTR_ABLE) == 0)) {
 2776                         /* Force async */
 2777                         spi->sync_period = 0;
 2778                         spi->sync_offset = 0;
 2779                 }
 2780 
 2781                 switch (spi->bus_width) {
 2782                 case MSG_EXT_WDTR_BUS_32_BIT:
 2783                         if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0
 2784                           || (inq_data->flags & SID_WBus32) != 0
 2785                           || cts->type == CTS_TYPE_USER_SETTINGS)
 2786                          && (cpi.hba_inquiry & PI_WIDE_32) != 0)
 2787                                 break;
 2788                         /* Fall Through to 16-bit */
 2789                 case MSG_EXT_WDTR_BUS_16_BIT:
 2790                         if (((device->flags & CAM_DEV_INQUIRY_DATA_VALID) == 0
 2791                           || (inq_data->flags & SID_WBus16) != 0
 2792                           || cts->type == CTS_TYPE_USER_SETTINGS)
 2793                          && (cpi.hba_inquiry & PI_WIDE_16) != 0) {
 2794                                 spi->bus_width = MSG_EXT_WDTR_BUS_16_BIT;
 2795                                 break;
 2796                         }
 2797                         /* Fall Through to 8-bit */
 2798                 default: /* New bus width?? */
 2799                 case MSG_EXT_WDTR_BUS_8_BIT:
 2800                         /* All targets can do this */
 2801                         spi->bus_width = MSG_EXT_WDTR_BUS_8_BIT;
 2802                         break;
 2803                 }
 2804 
 2805                 spi3caps = cpi.xport_specific.spi.ppr_options;
 2806                 if ((device->flags & CAM_DEV_INQUIRY_DATA_VALID) != 0
 2807                  && cts->type == CTS_TYPE_CURRENT_SETTINGS)
 2808                         spi3caps &= inq_data->spi3data;
 2809 
 2810                 if ((spi3caps & SID_SPI_CLOCK_DT) == 0)
 2811                         spi->ppr_options &= ~MSG_EXT_PPR_DT_REQ;
 2812 
 2813                 if ((spi3caps & SID_SPI_IUS) == 0)
 2814                         spi->ppr_options &= ~MSG_EXT_PPR_IU_REQ;
 2815 
 2816                 if ((spi3caps & SID_SPI_QAS) == 0)
 2817                         spi->ppr_options &= ~MSG_EXT_PPR_QAS_REQ;
 2818 
 2819                 /* No SPI Transfer settings are allowed unless we are wide */
 2820                 if (spi->bus_width == 0)
 2821                         spi->ppr_options = 0;
 2822 
 2823                 if ((spi->valid & CTS_SPI_VALID_DISC)
 2824                  && ((spi->flags & CTS_SPI_FLAGS_DISC_ENB) == 0)) {
 2825                         /*
 2826                          * Can't tag queue without disconnection.
 2827                          */
 2828                         scsi->flags &= ~CTS_SCSI_FLAGS_TAG_ENB;
 2829                         scsi->valid |= CTS_SCSI_VALID_TQ;
 2830                 }
 2831 
 2832                 /*
 2833                  * If we are currently performing tagged transactions to
 2834                  * this device and want to change its negotiation parameters,
 2835                  * go non-tagged for a bit to give the controller a chance to
 2836                  * negotiate unhampered by tag messages.
 2837                  */
 2838                 if (cts->type == CTS_TYPE_CURRENT_SETTINGS
 2839                  && (device->inq_flags & SID_CmdQue) != 0
 2840                  && (scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0
 2841                  && (spi->flags & (CTS_SPI_VALID_SYNC_RATE|
 2842                                    CTS_SPI_VALID_SYNC_OFFSET|
 2843                                    CTS_SPI_VALID_BUS_WIDTH)) != 0)
 2844                         scsi_toggle_tags(path);
 2845         }
 2846 
 2847         if (cts->type == CTS_TYPE_CURRENT_SETTINGS
 2848          && (scsi->valid & CTS_SCSI_VALID_TQ) != 0) {
 2849                 int device_tagenb;
 2850 
 2851                 /*
 2852                  * If we are transitioning from tags to no-tags or
 2853                  * vice-versa, we need to carefully freeze and restart
 2854                  * the queue so that we don't overlap tagged and non-tagged
 2855                  * commands.  We also temporarily stop tags if there is
 2856                  * a change in transfer negotiation settings to allow
 2857                  * "tag-less" negotiation.
 2858                  */
 2859                 if ((device->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
 2860                  || (device->inq_flags & SID_CmdQue) != 0)
 2861                         device_tagenb = TRUE;
 2862                 else
 2863                         device_tagenb = FALSE;
 2864 
 2865                 if (((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0
 2866                   && device_tagenb == FALSE)
 2867                  || ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) == 0
 2868                   && device_tagenb == TRUE)) {
 2869 
 2870                         if ((scsi->flags & CTS_SCSI_FLAGS_TAG_ENB) != 0) {
 2871                                 /*
 2872                                  * Delay change to use tags until after a
 2873                                  * few commands have gone to this device so
 2874                                  * the controller has time to perform transfer
 2875                                  * negotiations without tagged messages getting
 2876                                  * in the way.
 2877                                  */
 2878                                 device->tag_delay_count = CAM_TAG_DELAY_COUNT;
 2879                                 device->flags |= CAM_DEV_TAG_AFTER_COUNT;
 2880                         } else {
 2881                                 xpt_stop_tags(path);
 2882                         }
 2883                 }
 2884         }
 2885         if (async_update == FALSE)
 2886                 xpt_action_default((union ccb *)cts);
 2887 }
 2888 
 2889 static void
 2890 scsi_toggle_tags(struct cam_path *path)
 2891 {
 2892         struct cam_ed *dev;
 2893 
 2894         /*
 2895          * Give controllers a chance to renegotiate
 2896          * before starting tag operations.  We
 2897          * "toggle" tagged queuing off then on
 2898          * which causes the tag enable command delay
 2899          * counter to come into effect.
 2900          */
 2901         dev = path->device;
 2902         if ((dev->flags & CAM_DEV_TAG_AFTER_COUNT) != 0
 2903          || ((dev->inq_flags & SID_CmdQue) != 0
 2904           && (dev->inq_flags & (SID_Sync|SID_WBus16|SID_WBus32)) != 0)) {
 2905                 struct ccb_trans_settings cts;
 2906 
 2907                 xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NONE);
 2908                 cts.protocol = PROTO_SCSI;
 2909                 cts.protocol_version = PROTO_VERSION_UNSPECIFIED;
 2910                 cts.transport = XPORT_UNSPECIFIED;
 2911                 cts.transport_version = XPORT_VERSION_UNSPECIFIED;
 2912                 cts.proto_specific.scsi.flags = 0;
 2913                 cts.proto_specific.scsi.valid = CTS_SCSI_VALID_TQ;
 2914                 scsi_set_transfer_settings(&cts, path,
 2915                                           /*async_update*/TRUE);
 2916                 cts.proto_specific.scsi.flags = CTS_SCSI_FLAGS_TAG_ENB;
 2917                 scsi_set_transfer_settings(&cts, path,
 2918                                           /*async_update*/TRUE);
 2919         }
 2920 }
 2921 
 2922 /*
 2923  * Handle any per-device event notifications that require action by the XPT.
 2924  */
 2925 static void
 2926 scsi_dev_async(u_int32_t async_code, struct cam_eb *bus, struct cam_et *target,
 2927               struct cam_ed *device, void *async_arg)
 2928 {
 2929         cam_status status;
 2930         struct cam_path newpath;
 2931 
 2932         /*
 2933          * We only need to handle events for real devices.
 2934          */
 2935         if (target->target_id == CAM_TARGET_WILDCARD
 2936          || device->lun_id == CAM_LUN_WILDCARD)
 2937                 return;
 2938 
 2939         /*
 2940          * We need our own path with wildcards expanded to
 2941          * handle certain types of events.
 2942          */
 2943         if ((async_code == AC_SENT_BDR)
 2944          || (async_code == AC_BUS_RESET)
 2945          || (async_code == AC_INQ_CHANGED))
 2946                 status = xpt_compile_path(&newpath, NULL,
 2947                                           bus->path_id,
 2948                                           target->target_id,
 2949                                           device->lun_id);
 2950         else
 2951                 status = CAM_REQ_CMP_ERR;
 2952 
 2953         if (status == CAM_REQ_CMP) {
 2954 
 2955                 /*
 2956                  * Allow transfer negotiation to occur in a
 2957                  * tag free environment and after settle delay.
 2958                  */
 2959                 if (async_code == AC_SENT_BDR
 2960                  || async_code == AC_BUS_RESET) {
 2961                         cam_freeze_devq(&newpath); 
 2962                         cam_release_devq(&newpath,
 2963                                 RELSIM_RELEASE_AFTER_TIMEOUT,
 2964                                 /*reduction*/0,
 2965                                 /*timeout*/scsi_delay,
 2966                                 /*getcount_only*/0);
 2967                         scsi_toggle_tags(&newpath);
 2968                 }
 2969 
 2970                 if (async_code == AC_INQ_CHANGED) {
 2971                         /*
 2972                          * We've sent a start unit command, or
 2973                          * something similar to a device that
 2974                          * may have caused its inquiry data to
 2975                          * change. So we re-scan the device to
 2976                          * refresh the inquiry data for it.
 2977                          */
 2978                         scsi_scan_lun(newpath.periph, &newpath,
 2979                                      CAM_EXPECT_INQ_CHANGE, NULL);
 2980                 }
 2981                 xpt_release_path(&newpath);
 2982         } else if (async_code == AC_LOST_DEVICE &&
 2983             (device->flags & CAM_DEV_UNCONFIGURED) == 0) {
 2984                 device->flags |= CAM_DEV_UNCONFIGURED;
 2985                 xpt_release_device(device);
 2986         } else if (async_code == AC_TRANSFER_NEG) {
 2987                 struct ccb_trans_settings *settings;
 2988                 struct cam_path path;
 2989 
 2990                 settings = (struct ccb_trans_settings *)async_arg;
 2991                 xpt_compile_path(&path, NULL, bus->path_id, target->target_id,
 2992                                  device->lun_id);
 2993                 scsi_set_transfer_settings(settings, &path,
 2994                                           /*async_update*/TRUE);
 2995                 xpt_release_path(&path);
 2996         }
 2997 }
 2998 
 2999 static void
 3000 scsi_announce_periph(struct cam_periph *periph)
 3001 {
 3002         struct  ccb_pathinq cpi;
 3003         struct  ccb_trans_settings cts;
 3004         struct  cam_path *path = periph->path;
 3005         u_int   speed;
 3006         u_int   freq;
 3007         u_int   mb;
 3008 
 3009         cam_periph_assert(periph, MA_OWNED);
 3010 
 3011         xpt_setup_ccb(&cts.ccb_h, path, CAM_PRIORITY_NORMAL);
 3012         cts.ccb_h.func_code = XPT_GET_TRAN_SETTINGS;
 3013         cts.type = CTS_TYPE_CURRENT_SETTINGS;
 3014         xpt_action((union ccb*)&cts);
 3015         if (cam_ccb_status((union ccb *)&cts) != CAM_REQ_CMP)
 3016                 return;
 3017         /* Ask the SIM for its base transfer speed */
 3018         xpt_setup_ccb(&cpi.ccb_h, path, CAM_PRIORITY_NORMAL);
 3019         cpi.ccb_h.func_code = XPT_PATH_INQ;
 3020         xpt_action((union ccb *)&cpi);
 3021         /* Report connection speed */ 
 3022         speed = cpi.base_transfer_speed;
 3023         freq = 0;
 3024         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) {
 3025                 struct  ccb_trans_settings_spi *spi =
 3026                     &cts.xport_specific.spi;
 3027 
 3028                 if ((spi->valid & CTS_SPI_VALID_SYNC_OFFSET) != 0
 3029                   && spi->sync_offset != 0) {
 3030                         freq = scsi_calc_syncsrate(spi->sync_period);
 3031                         speed = freq;
 3032                 }
 3033                 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0)
 3034                         speed *= (0x01 << spi->bus_width);
 3035         }
 3036         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) {
 3037                 struct  ccb_trans_settings_fc *fc =
 3038                     &cts.xport_specific.fc;
 3039 
 3040                 if (fc->valid & CTS_FC_VALID_SPEED)
 3041                         speed = fc->bitrate;
 3042         }
 3043         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SAS) {
 3044                 struct  ccb_trans_settings_sas *sas =
 3045                     &cts.xport_specific.sas;
 3046 
 3047                 if (sas->valid & CTS_SAS_VALID_SPEED)
 3048                         speed = sas->bitrate;
 3049         }
 3050         mb = speed / 1000;
 3051         if (mb > 0)
 3052                 printf("%s%d: %d.%03dMB/s transfers",
 3053                        periph->periph_name, periph->unit_number,
 3054                        mb, speed % 1000);
 3055         else
 3056                 printf("%s%d: %dKB/s transfers", periph->periph_name,
 3057                        periph->unit_number, speed);
 3058         /* Report additional information about SPI connections */
 3059         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_SPI) {
 3060                 struct  ccb_trans_settings_spi *spi;
 3061 
 3062                 spi = &cts.xport_specific.spi;
 3063                 if (freq != 0) {
 3064                         printf(" (%d.%03dMHz%s, offset %d", freq / 1000,
 3065                                freq % 1000,
 3066                                (spi->ppr_options & MSG_EXT_PPR_DT_REQ) != 0
 3067                              ? " DT" : "",
 3068                                spi->sync_offset);
 3069                 }
 3070                 if ((spi->valid & CTS_SPI_VALID_BUS_WIDTH) != 0
 3071                  && spi->bus_width > 0) {
 3072                         if (freq != 0) {
 3073                                 printf(", ");
 3074                         } else {
 3075                                 printf(" (");
 3076                         }
 3077                         printf("%dbit)", 8 * (0x01 << spi->bus_width));
 3078                 } else if (freq != 0) {
 3079                         printf(")");
 3080                 }
 3081         }
 3082         if (cts.ccb_h.status == CAM_REQ_CMP && cts.transport == XPORT_FC) {
 3083                 struct  ccb_trans_settings_fc *fc;
 3084 
 3085                 fc = &cts.xport_specific.fc;
 3086                 if (fc->valid & CTS_FC_VALID_WWNN)
 3087                         printf(" WWNN 0x%llx", (long long) fc->wwnn);
 3088                 if (fc->valid & CTS_FC_VALID_WWPN)
 3089                         printf(" WWPN 0x%llx", (long long) fc->wwpn);
 3090                 if (fc->valid & CTS_FC_VALID_PORT)
 3091                         printf(" PortID 0x%x", fc->port);
 3092         }
 3093         printf("\n");
 3094 }
 3095 

Cache object: 6c3c2fc944c1ad90f7dfda58f60735cc


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