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

Cache object: 0ed30fb70286f5880a3aa22d13518ae3


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