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/dev/scsipi/scsiconf.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 /*      $NetBSD: scsiconf.c,v 1.303 2022/10/15 18:42:49 jmcneill Exp $  */
    2 
    3 /*-
    4  * Copyright (c) 1998, 1999, 2004 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
    9  * Simulation Facility, NASA Ames Research Center.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   30  * POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 /*
   34  * Originally written by Julian Elischer (julian@tfs.com)
   35  * for TRW Financial Systems for use under the MACH(2.5) operating system.
   36  *
   37  * TRW Financial Systems, in accordance with their agreement with Carnegie
   38  * Mellon University, makes this software available to CMU to distribute
   39  * or use in any manner that they see fit as long as this message is kept with
   40  * the software. For this reason TFS also grants any other persons or
   41  * organisations permission to use or modify this software.
   42  *
   43  * TFS supplies this software to be publicly redistributed
   44  * on the understanding that TFS is not responsible for the correct
   45  * functioning of this software in any circumstances.
   46  *
   47  * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
   48  */
   49 
   50 #include <sys/cdefs.h>
   51 __KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.303 2022/10/15 18:42:49 jmcneill Exp $");
   52 
   53 #include <sys/param.h>
   54 #include <sys/systm.h>
   55 #include <sys/kernel.h>
   56 #include <sys/proc.h>
   57 #include <sys/kthread.h>
   58 #include <sys/malloc.h>
   59 #include <sys/mutex.h>
   60 #include <sys/once.h>
   61 #include <sys/device.h>
   62 #include <sys/conf.h>
   63 #include <sys/fcntl.h>
   64 #include <sys/scsiio.h>
   65 #include <sys/queue.h>
   66 #include <sys/atomic.h>
   67 #include <sys/kmem.h>
   68 
   69 #include <dev/scsipi/scsi_all.h>
   70 #include <dev/scsipi/scsipi_all.h>
   71 #include <dev/scsipi/scsiconf.h>
   72 
   73 #include "locators.h"
   74 
   75 static const struct scsipi_periphsw scsi_probe_dev = {
   76         NULL,
   77         NULL,
   78         NULL,
   79         NULL,
   80 };
   81 
   82 struct scsi_initq {
   83         struct scsipi_channel *sc_channel;
   84         TAILQ_ENTRY(scsi_initq) scsi_initq;
   85 };
   86 
   87 static ONCE_DECL(scsi_conf_ctrl);
   88 static TAILQ_HEAD(, scsi_initq) scsi_initq_head;
   89 static kmutex_t                 scsibus_qlock;
   90 static kcondvar_t               scsibus_qcv;
   91 
   92 static int      scsi_probe_device(struct scsibus_softc *, int, int);
   93 
   94 static int      scsibusmatch(device_t, cfdata_t, void *);
   95 static void     scsibusattach(device_t, device_t, void *);
   96 static int      scsibusdetach(device_t, int flags);
   97 static int      scsibusrescan(device_t, const char *, const int *);
   98 static void     scsidevdetached(device_t, device_t);
   99 
  100 CFATTACH_DECL3_NEW(scsibus, sizeof(struct scsibus_softc),
  101     scsibusmatch, scsibusattach, scsibusdetach, NULL,
  102     scsibusrescan, scsidevdetached, DVF_DETACH_SHUTDOWN);
  103 
  104 extern struct cfdriver scsibus_cd;
  105 
  106 static dev_type_open(scsibusopen);
  107 static dev_type_close(scsibusclose);
  108 static dev_type_ioctl(scsibusioctl);
  109 
  110 const struct cdevsw scsibus_cdevsw = {
  111         .d_open = scsibusopen,
  112         .d_close = scsibusclose,
  113         .d_read = noread,
  114         .d_write = nowrite,
  115         .d_ioctl = scsibusioctl,
  116         .d_stop = nostop,
  117         .d_tty = notty,
  118         .d_poll = nopoll,
  119         .d_mmap = nommap,
  120         .d_kqfilter = nokqfilter,
  121         .d_discard = nodiscard,
  122         .d_flag = D_OTHER | D_MPSAFE
  123 };
  124 
  125 static int      scsibusprint(void *, const char *);
  126 static void     scsibus_discover_thread(void *);
  127 static void     scsibus_config(struct scsibus_softc *);
  128 
  129 static int
  130 scsibus_init(void)
  131 {
  132 
  133         TAILQ_INIT(&scsi_initq_head);
  134         mutex_init(&scsibus_qlock, MUTEX_DEFAULT, IPL_NONE);
  135         cv_init(&scsibus_qcv, "scsinitq");
  136         return 0;
  137 }
  138 
  139 static int
  140 scsibusmatch(device_t parent, cfdata_t cf, void *aux)
  141 {
  142         struct scsipi_channel *chan = aux;
  143 
  144         if (SCSIPI_BUSTYPE_TYPE(chan->chan_bustype->bustype_type) !=
  145             SCSIPI_BUSTYPE_SCSI)
  146                 return 0;
  147 
  148         if (cf->cf_loc[SCSICF_CHANNEL] != chan->chan_channel &&
  149             cf->cf_loc[SCSICF_CHANNEL] != SCSICF_CHANNEL_DEFAULT)
  150                 return (0);
  151 
  152         return (1);
  153 }
  154 
  155 static void
  156 scsibusattach(device_t parent, device_t self, void *aux)
  157 {
  158         struct scsibus_softc *sc = device_private(self);
  159         struct scsipi_channel *chan = aux;
  160         struct scsi_initq *scsi_initq;
  161 
  162         if (!pmf_device_register(self, NULL, NULL))
  163                 aprint_error_dev(self, "couldn't establish power handler\n");
  164 
  165         sc->sc_dev = self;
  166         sc->sc_channel = chan;
  167         chan->chan_name = device_xname(sc->sc_dev);
  168 
  169         aprint_naive(": SCSI bus\n");
  170         aprint_normal(": %d target%s, %d lun%s per target\n",
  171             chan->chan_ntargets,
  172             chan->chan_ntargets == 1 ? "" : "s",
  173             chan->chan_nluns,
  174             chan->chan_nluns == 1 ? "" : "s");
  175 
  176         /*
  177          * XXX 
  178          * newer adapters support more than 256 outstanding commands
  179          * per periph and don't use the tag (they eventually allocate one
  180          * internally). Right now scsipi always allocate a tag and
  181          * is limited to 256 tags, per scsi specs.
  182          * this should be revisited
  183          */
  184         if (chan->chan_flags & SCSIPI_CHAN_OPENINGS) {
  185                 if (chan->chan_max_periph > 256)
  186                         chan->chan_max_periph = 256;
  187         } else {
  188                 if (chan->chan_adapter->adapt_max_periph > 256)
  189                         chan->chan_adapter->adapt_max_periph = 256;
  190         }
  191 
  192         if (atomic_inc_uint_nv(&chan_running(chan)) == 1)
  193                 mutex_init(chan_mtx(chan), MUTEX_DEFAULT, IPL_BIO);
  194 
  195         cv_init(&chan->chan_cv_thr, "scshut");
  196         cv_init(&chan->chan_cv_comp, "sccomp");
  197         cv_init(&chan->chan_cv_xs, "xscmd");
  198 
  199         if (scsipi_adapter_addref(chan->chan_adapter))
  200                 return;
  201 
  202         RUN_ONCE(&scsi_conf_ctrl, scsibus_init);
  203 
  204         /* Initialize the channel structure first */
  205         chan->chan_init_cb = NULL;
  206         chan->chan_init_cb_arg = NULL;
  207 
  208         scsi_initq = malloc(sizeof(struct scsi_initq), M_DEVBUF, M_WAITOK);
  209         scsi_initq->sc_channel = chan;
  210         TAILQ_INSERT_TAIL(&scsi_initq_head, scsi_initq, scsi_initq);
  211         config_pending_incr(sc->sc_dev);
  212         if (scsipi_channel_init(chan)) {
  213                 aprint_error_dev(sc->sc_dev, "failed to init channel\n");
  214                 return;
  215         }
  216 
  217         /*
  218          * Create the discover thread
  219          */
  220         if (kthread_create(PRI_NONE, 0, NULL, scsibus_discover_thread, sc,
  221             &chan->chan_dthread, "%s-d", chan->chan_name)) {
  222                 aprint_error_dev(sc->sc_dev, "unable to create discovery "
  223                     "thread for channel %d\n", chan->chan_channel);
  224                 return;
  225         }
  226 }
  227 
  228 static void
  229 scsibus_discover_thread(void *arg)
  230 {
  231         struct scsibus_softc *sc = arg;
  232 
  233         scsibus_config(sc);
  234         sc->sc_channel->chan_dthread = NULL;
  235         kthread_exit(0);
  236 }
  237 
  238 static void
  239 scsibus_config(struct scsibus_softc *sc)
  240 {
  241         struct scsipi_channel *chan = sc->sc_channel;
  242         struct scsi_initq *scsi_initq;
  243 
  244 #ifndef SCSI_DELAY
  245 #define SCSI_DELAY 2
  246 #endif
  247         if ((chan->chan_flags & SCSIPI_CHAN_NOSETTLE) == 0 &&
  248             SCSI_DELAY > 0) {
  249                 aprint_normal_dev(sc->sc_dev,
  250                     "waiting %d seconds for devices to settle...\n",
  251                     SCSI_DELAY);
  252                 /* ...an identifier we know no one will use... */
  253                 kpause("scsidly", false, SCSI_DELAY * hz, NULL);
  254         }
  255 
  256         /* Make sure the devices probe in scsibus order to avoid jitter. */
  257         mutex_enter(&scsibus_qlock);
  258         for (;;) {
  259                 scsi_initq = TAILQ_FIRST(&scsi_initq_head);
  260                 if (scsi_initq->sc_channel == chan)
  261                         break;
  262                 cv_wait(&scsibus_qcv, &scsibus_qlock);
  263         }
  264         mutex_exit(&scsibus_qlock);
  265 
  266         scsi_probe_bus(sc, -1, -1);
  267 
  268         mutex_enter(&scsibus_qlock);
  269         TAILQ_REMOVE(&scsi_initq_head, scsi_initq, scsi_initq);
  270         cv_broadcast(&scsibus_qcv);
  271         mutex_exit(&scsibus_qlock);
  272 
  273         free(scsi_initq, M_DEVBUF);
  274 
  275         scsipi_adapter_delref(chan->chan_adapter);
  276 
  277         config_pending_decr(sc->sc_dev);
  278 }
  279 
  280 static int
  281 scsibusdetach(device_t self, int flags)
  282 {
  283         struct scsibus_softc *sc = device_private(self);
  284         struct scsipi_channel *chan = sc->sc_channel;
  285         int error;
  286 
  287         /*
  288          * Defer while discovery thread is running
  289          */
  290         while (chan->chan_dthread != NULL)
  291                 kpause("scsibusdet", false, hz, NULL);
  292 
  293         /*
  294          * Detach all of the periphs.
  295          */
  296         error = scsipi_target_detach(chan, -1, -1, flags);
  297         if (error)
  298                 return error;
  299 
  300         pmf_device_deregister(self);
  301 
  302         /*
  303          * Shut down the channel.
  304          */
  305         scsipi_channel_shutdown(chan);
  306 
  307         cv_destroy(&chan->chan_cv_xs);
  308         cv_destroy(&chan->chan_cv_comp);
  309         cv_destroy(&chan->chan_cv_thr);
  310 
  311         membar_release();
  312         if (atomic_dec_uint_nv(&chan_running(chan)) == 0) {
  313                 membar_acquire();
  314                 mutex_destroy(chan_mtx(chan));
  315         }
  316 
  317         return 0;
  318 }
  319 
  320 static int
  321 lun_compar(const void *a, const void *b)
  322 {
  323         const uint16_t * const la = a, * const lb = b;
  324 
  325         if (*la < *lb)
  326                 return -1;
  327         if (*la > *lb)
  328                 return 1;
  329         return 0;
  330 }
  331 
  332 static int
  333 scsi_report_luns(struct scsibus_softc *sc, int target,
  334     uint16_t ** const luns, size_t *nluns)
  335 {
  336         struct scsi_report_luns replun;
  337         struct scsi_report_luns_header *rlr;
  338         struct scsi_report_luns_lun *lunp;
  339 
  340         struct scsipi_channel *chan = sc->sc_channel;
  341         struct scsipi_inquiry_data inqbuf;
  342         struct scsipi_periph *periph;
  343         uint16_t tmp;
  344 
  345         int error;
  346         size_t i, rlrlen, rlrlenmin;
  347 
  348         memset(&replun, 0, sizeof(replun));
  349 
  350         periph = scsipi_alloc_periph(M_WAITOK);
  351         periph->periph_channel = chan;
  352         periph->periph_switch = &scsi_probe_dev;
  353 
  354         periph->periph_target = target;
  355         periph->periph_lun = 0;
  356         periph->periph_quirks = chan->chan_defquirks;
  357 
  358         if ((error = scsipi_inquire(periph, &inqbuf,
  359             XS_CTL_DISCOVERY | XS_CTL_SILENT)))
  360                 goto end2;
  361         periph->periph_version = inqbuf.version & SID_ANSII;
  362         if (periph->periph_version < 3) {
  363                 error = ENOTSUP;
  364                 goto end2;
  365         }
  366 
  367         rlrlen = rlrlenmin = sizeof(*rlr) + sizeof(*lunp) * 1;
  368 
  369 again:
  370         rlr = kmem_zalloc(rlrlen, KM_SLEEP);
  371 
  372         replun.opcode = SCSI_REPORT_LUNS;
  373         replun.selectreport = SELECTREPORT_NORMAL;
  374         _lto4b(rlrlen, replun.alloclen);
  375 
  376         error = scsipi_command(periph, (void *)&replun, sizeof(replun),
  377             (void *)rlr, rlrlen, SCSIPIRETRIES, 10000, NULL,
  378             XS_CTL_DATA_IN | XS_CTL_DISCOVERY | XS_CTL_SILENT);
  379         if (error)
  380                 goto end;
  381 
  382         if (sizeof(*rlr) + _4btol(rlr->length) > rlrlen &&
  383             sizeof(*rlr) + _4btol(rlr->length) <= 32) {
  384                 const size_t old_rlrlen = rlrlen;
  385                 rlrlen = sizeof(*rlr) + uimin(_4btol(rlr->length),
  386                     16383 * sizeof(*lunp));
  387                 kmem_free(rlr, old_rlrlen);
  388                 rlr = NULL;
  389                 if (rlrlen < rlrlenmin) {
  390                         error = EIO;
  391                         goto end;
  392                 }
  393                 goto again;
  394         }
  395 
  396         KASSERT(nluns != NULL);
  397         *nluns = (rlrlen - sizeof(*rlr)) / sizeof(*lunp);
  398 
  399         KASSERT(luns != NULL);
  400         *luns = kmem_alloc(*nluns * sizeof(**luns), KM_SLEEP);
  401 
  402         for (i = 0; i < *nluns; i++) {
  403                 lunp = &((struct scsi_report_luns_lun *)&rlr[1])[i];
  404                 switch (lunp->lun[0] & 0xC0) {
  405                 default:
  406                         scsi_print_addr(periph);
  407                         printf("LUN %016"PRIx64" ignored\n", _8btol(lunp->lun));
  408                         (*luns)[i] = 0;
  409                         break;
  410                 case 0x40:
  411                         (*luns)[i] = _2btol(&lunp->lun[0]) & 0x3FFF;
  412                         break;
  413                 case 0x00:
  414                         (*luns)[i] = _2btol(&lunp->lun[0]) & 0x00FF;
  415                         break;
  416                 }
  417         }
  418 
  419         kheapsort(*luns, *nluns, sizeof(**luns), lun_compar, &tmp);
  420 
  421 end:
  422         if (rlr)
  423                 kmem_free(rlr, rlrlen);
  424 end2:
  425         scsipi_free_periph(periph);
  426         return error;
  427 }
  428 
  429 static void
  430 scsi_discover_luns(struct scsibus_softc *sc, int target, int minlun, int maxlun)
  431 {
  432         uint16_t *luns = NULL;  /* XXX gcc */
  433         size_t nluns = 0;       /* XXX gcc */
  434 
  435         if (scsi_report_luns(sc, target, &luns, &nluns) == 0) {
  436                 for (size_t i = 0; i < nluns; i++)
  437                         if (luns[i] >= minlun && luns[i] <= maxlun)
  438                                 scsi_probe_device(sc, target, luns[i]);
  439                 kmem_free(luns, sizeof(*luns) * nluns);
  440                 return;
  441         }
  442 
  443         for (int lun = minlun; lun <= maxlun; lun++) {
  444                 /*
  445                  * See if there's a device present, and configure it.
  446                  */
  447                 if (scsi_probe_device(sc, target, lun) == 0)
  448                         break;
  449                 /* otherwise something says we should look further */
  450         }
  451 }
  452 
  453 /*
  454  * Probe the requested scsi bus. It must be already set up.
  455  * target and lun optionally narrow the search if not -1
  456  */
  457 int
  458 scsi_probe_bus(struct scsibus_softc *sc, int target, int lun)
  459 {
  460         struct scsipi_channel *chan = sc->sc_channel;
  461         int maxtarget, mintarget, maxlun, minlun;
  462         int error;
  463 
  464         if (target == -1) {
  465                 maxtarget = chan->chan_ntargets - 1;
  466                 mintarget = 0;
  467         } else {
  468                 if (target < 0 || target >= chan->chan_ntargets)
  469                         return (EINVAL);
  470                 maxtarget = mintarget = target;
  471         }
  472 
  473         if (lun == -1) {
  474                 maxlun = chan->chan_nluns - 1;
  475                 minlun = 0;
  476         } else {
  477                 if (lun < 0 || lun >= chan->chan_nluns)
  478                         return (EINVAL);
  479                 maxlun = minlun = lun;
  480         }
  481 
  482         /*
  483          * Some HBAs provide an abstracted view of the bus; give them an
  484          * opportunity to re-scan it before we do.
  485          */
  486         scsipi_adapter_ioctl(chan, SCBUSIOLLSCAN, NULL, 0, curproc);
  487 
  488         if ((error = scsipi_adapter_addref(chan->chan_adapter)) != 0)
  489                 goto ret;
  490         for (target = mintarget; target <= maxtarget; target++) {
  491                 if (target == chan->chan_id)
  492                         continue;
  493 
  494                 scsi_discover_luns(sc, target, minlun, maxlun);
  495 
  496                 /*
  497                  * Now that we've discovered all of the LUNs on this
  498                  * I_T Nexus, update the xfer mode for all of them
  499                  * that we know about.
  500                  */
  501                 scsipi_set_xfer_mode(chan, target, 1);
  502         }
  503 
  504         scsipi_adapter_delref(chan->chan_adapter);
  505 ret:
  506         return (error);
  507 }
  508 
  509 static int
  510 scsibusrescan(device_t sc, const char *ifattr, const int *locators)
  511 {
  512 
  513         KASSERT(ifattr && !strcmp(ifattr, "scsibus"));
  514         KASSERT(locators);
  515 
  516         return (scsi_probe_bus(device_private(sc),
  517                 locators[SCSIBUSCF_TARGET], locators[SCSIBUSCF_LUN]));
  518 }
  519 
  520 static void
  521 scsidevdetached(device_t self, device_t child)
  522 {
  523         struct scsibus_softc *sc = device_private(self);
  524         struct scsipi_channel *chan = sc->sc_channel;
  525         struct scsipi_periph *periph;
  526         int target, lun;
  527 
  528         target = device_locator(child, SCSIBUSCF_TARGET);
  529         lun = device_locator(child, SCSIBUSCF_LUN);
  530 
  531         mutex_enter(chan_mtx(chan));
  532 
  533         periph = scsipi_lookup_periph_locked(chan, target, lun);
  534         KASSERT(periph != NULL && periph->periph_dev == child);
  535 
  536         scsipi_remove_periph(chan, periph);
  537         scsipi_free_periph(periph);
  538 
  539         mutex_exit(chan_mtx(chan));
  540 }
  541 
  542 /*
  543  * Print out autoconfiguration information for a subdevice.
  544  *
  545  * This is a slight abuse of 'standard' autoconfiguration semantics,
  546  * because 'print' functions don't normally print the colon and
  547  * device information.  However, in this case that's better than
  548  * either printing redundant information before the attach message,
  549  * or having the device driver call a special function to print out
  550  * the standard device information.
  551  */
  552 static int
  553 scsibusprint(void *aux, const char *pnp)
  554 {
  555         struct scsipibus_attach_args *sa = aux;
  556         struct scsipi_inquiry_pattern *inqbuf;
  557         u_int8_t type;
  558         const char *dtype;
  559         char vendor[33], product[65], revision[17];
  560         int target, lun;
  561 
  562         if (pnp != NULL)
  563                 aprint_normal("%s", pnp);
  564 
  565         inqbuf = &sa->sa_inqbuf;
  566 
  567         target = sa->sa_periph->periph_target;
  568         lun = sa->sa_periph->periph_lun;
  569         type = inqbuf->type & SID_TYPE;
  570 
  571         dtype = scsipi_dtype(type);
  572 
  573         strnvisx(vendor, sizeof(vendor), inqbuf->vendor, 8,
  574             VIS_TRIM|VIS_SAFE|VIS_OCTAL);
  575         strnvisx(product, sizeof(product), inqbuf->product, 16,
  576             VIS_TRIM|VIS_SAFE|VIS_OCTAL);
  577         strnvisx(revision, sizeof(revision), inqbuf->revision, 4,
  578             VIS_TRIM|VIS_SAFE|VIS_OCTAL);
  579 
  580         aprint_normal(" target %d lun %d: <%s, %s, %s> %s %s%s",
  581                       target, lun, vendor, product, revision, dtype,
  582                       inqbuf->removable ? "removable" : "fixed",
  583                       (sa->sa_periph->periph_opcs != NULL)
  584                         ? " timeout-info" : "");
  585 
  586         return (UNCONF);
  587 }
  588 
  589 static const struct scsi_quirk_inquiry_pattern scsi_quirk_patterns[] = {
  590         {{T_DIRECT, T_REMOV,
  591          "Apple   ", "iPod            ", ""},     PQUIRK_START},
  592         {{T_CDROM, T_REMOV,
  593          "CHINON  ", "CD-ROM CDS-431  ", ""},     PQUIRK_NOLUNS},
  594         {{T_CDROM, T_REMOV,
  595          "CHINON  ", "CD-ROM CDS-435  ", ""},     PQUIRK_NOLUNS},
  596         {{T_CDROM, T_REMOV,
  597          "Chinon  ", "CD-ROM CDS-525  ", ""},     PQUIRK_NOLUNS},
  598         {{T_CDROM, T_REMOV,
  599          "CHINON  ", "CD-ROM CDS-535  ", ""},     PQUIRK_NOLUNS},
  600         {{T_CDROM, T_REMOV,
  601          "DEC     ", "RRD42   (C) DEC ", ""},     PQUIRK_NOLUNS},
  602         {{T_CDROM, T_REMOV,
  603          "DENON   ", "DRD-25X         ", "V"},    PQUIRK_NOLUNS},
  604         {{T_CDROM, T_REMOV,
  605          "GENERIC ", "CRD-BP2         ", ""},     PQUIRK_NOLUNS},
  606         {{T_CDROM, T_REMOV,
  607          "HP      ", "C4324/C4325     ", ""},     PQUIRK_NOLUNS},
  608         {{T_CDROM, T_REMOV,
  609          "IMS     ", "CDD521/10       ", "2.06"}, PQUIRK_NOLUNS},
  610         {{T_CDROM, T_REMOV,
  611          "MATSHITA", "CD-ROM CR-5XX   ", "1.0b"}, PQUIRK_NOLUNS},
  612         {{T_CDROM, T_REMOV,
  613          "MEDAVIS ", "RENO CD-ROMX2A  ", ""},     PQUIRK_NOLUNS},
  614         {{T_CDROM, T_REMOV,
  615          "MEDIAVIS", "CDR-H93MV       ", "1.3"},  PQUIRK_NOLUNS},
  616         {{T_CDROM, T_REMOV,
  617          "NEC     ", "CD-ROM DRIVE:502", ""},     PQUIRK_NOLUNS},
  618         {{T_CDROM, T_REMOV,
  619          "NEC     ", "CD-ROM DRIVE:55 ", ""},     PQUIRK_NOLUNS},
  620         {{T_CDROM, T_REMOV,
  621          "NEC     ", "CD-ROM DRIVE:83 ", ""},     PQUIRK_NOLUNS},
  622         {{T_CDROM, T_REMOV,
  623          "NEC     ", "CD-ROM DRIVE:84 ", ""},     PQUIRK_NOLUNS},
  624         {{T_CDROM, T_REMOV,
  625          "NEC     ", "CD-ROM DRIVE:841", ""},     PQUIRK_NOLUNS},
  626         {{T_CDROM, T_REMOV,
  627          "OLYMPUS ", "CDS620E         ", "1.1d"},
  628                                PQUIRK_NOLUNS|PQUIRK_NOSYNC|PQUIRK_NOCAPACITY},
  629         {{T_CDROM, T_REMOV,
  630          "PIONEER ", "CD-ROM DR-124X  ", "1.01"}, PQUIRK_NOLUNS},
  631         {{T_CDROM, T_REMOV,
  632          "PLEXTOR ", "CD-ROM PX-4XCS  ", "1.01"},
  633                                PQUIRK_NOLUNS|PQUIRK_NOSYNC},
  634         {{T_CDROM, T_REMOV,
  635          "SONY    ", "CD-ROM CDU-541  ", ""},     PQUIRK_NOLUNS},
  636         {{T_CDROM, T_REMOV,
  637          "SONY    ", "CD-ROM CDU-55S  ", ""},     PQUIRK_NOLUNS},
  638         {{T_CDROM, T_REMOV,
  639          "SONY    ", "CD-ROM CDU-561  ", ""},     PQUIRK_NOLUNS},
  640         {{T_CDROM, T_REMOV,
  641          "SONY    ", "CD-ROM CDU-76S", ""},
  642                                 PQUIRK_NOLUNS|PQUIRK_NOSYNC|PQUIRK_NOWIDE},
  643         {{T_CDROM, T_REMOV,
  644          "SONY    ", "CD-ROM CDU-8003A", ""},     PQUIRK_NOLUNS},
  645         {{T_CDROM, T_REMOV,
  646          "SONY    ", "CD-ROM CDU-8012 ", ""},     PQUIRK_NOLUNS},
  647         {{T_CDROM, T_REMOV,
  648          "TEAC    ", "CD-ROM          ", "1.06"}, PQUIRK_NOLUNS},
  649         {{T_CDROM, T_REMOV,
  650          "TEAC    ", "CD-ROM CD-56S   ", "1.0B"}, PQUIRK_NOLUNS},
  651         {{T_CDROM, T_REMOV,
  652          "TEXEL   ", "CD-ROM          ", "1.06"}, PQUIRK_NOLUNS},
  653         {{T_CDROM, T_REMOV,
  654          "TEXEL   ", "CD-ROM DM-XX24 K", "1.09"}, PQUIRK_NOLUNS},
  655         {{T_CDROM, T_REMOV,
  656          "TEXEL   ", "CD-ROM DM-XX24 K", "1.10"}, PQUIRK_NOLUNS},
  657         {{T_CDROM, T_REMOV,
  658          "TOSHIBA ", "XM-4101TASUNSLCD", ""}, PQUIRK_NOLUNS|PQUIRK_NOSYNC},
  659         /* "IBM CDRM00201     !F" 0724 is an IBM OEM Toshiba XM-4101BME */
  660         {{T_CDROM, T_REMOV,
  661          "IBM     ", "CDRM00201     !F", "0724"}, PQUIRK_NOLUNS|PQUIRK_NOSYNC},
  662         {{T_CDROM, T_REMOV,
  663          "ShinaKen", "CD-ROM DM-3x1S",   "1.04"}, PQUIRK_NOLUNS},
  664         {{T_CDROM, T_REMOV,
  665          "JVC     ", "R2626",            ""},     PQUIRK_NOLUNS},
  666         {{T_CDROM, T_REMOV,
  667          "YAMAHA", "CRW8424S",           ""},     PQUIRK_NOLUNS},
  668         {{T_CDROM, T_REMOV,
  669          "NEC     ", "CD-ROM DRIVE:222", ""},     PQUIRK_NOLUNS|PQUIRK_NOSYNC},
  670 
  671         {{T_DIRECT, T_FIXED,
  672          "MICROP  ", "1588-15MBSUN0669", ""},     PQUIRK_AUTOSAVE},
  673         {{T_DIRECT, T_FIXED,
  674          "MICROP  ", "2217-15MQ1091501", ""},     PQUIRK_NOSYNCCACHE},
  675         {{T_OPTICAL, T_REMOV,
  676          "EPSON   ", "OMD-5010        ", "3.08"}, PQUIRK_NOLUNS},
  677         {{T_DIRECT, T_FIXED,
  678          "ADAPTEC ", "AEC-4412BD",       "1.2A"}, PQUIRK_NOMODESENSE},
  679         {{T_DIRECT, T_FIXED,
  680          "ADAPTEC ", "ACB-4000",         ""},     PQUIRK_FORCELUNS|PQUIRK_AUTOSAVE|PQUIRK_NOMODESENSE},
  681         {{T_DIRECT, T_FIXED,
  682          "DEC     ", "RZ55     (C) DEC", ""},     PQUIRK_AUTOSAVE},
  683         {{T_DIRECT, T_FIXED,
  684          "EMULEX  ", "MD21/S2     ESDI", "A00"},
  685                                 PQUIRK_FORCELUNS|PQUIRK_AUTOSAVE},
  686         {{T_DIRECT, T_FIXED,
  687          "MICROP",  "1548-15MZ1077801",  "HZ2P"}, PQUIRK_NOTAG},
  688         {{T_DIRECT, T_FIXED,
  689          "HP      ", "C372",             ""},     PQUIRK_NOTAG},
  690         {{T_DIRECT, T_FIXED,
  691          "IBMRAID ", "0662S",            ""},     PQUIRK_AUTOSAVE},
  692         {{T_DIRECT, T_FIXED,
  693          "IBM     ", "0663H",            ""},     PQUIRK_AUTOSAVE},
  694         {{T_DIRECT, T_FIXED,
  695          "IBM",      "0664",             ""},     PQUIRK_AUTOSAVE},
  696         {{T_DIRECT, T_FIXED,
  697         /* improperly report DT-only sync mode */
  698          "IBM     ", "DXHS36D",          ""},
  699                                 PQUIRK_CAP_SYNC|PQUIRK_CAP_WIDE16},
  700         {{T_DIRECT, T_FIXED,
  701          "IBM     ", "DXHS18Y",          ""},
  702                                 PQUIRK_CAP_SYNC|PQUIRK_CAP_WIDE16},
  703         {{T_DIRECT, T_FIXED,
  704          "IBM     ", "H3171-S2",         ""},
  705                                 PQUIRK_NOLUNS|PQUIRK_AUTOSAVE},
  706         {{T_DIRECT, T_FIXED,
  707          "IBM     ", "KZ-C",             ""},     PQUIRK_AUTOSAVE},
  708         /* Broken IBM disk */
  709         {{T_DIRECT, T_FIXED,
  710          ""        , "DFRSS2F",          ""},     PQUIRK_AUTOSAVE},
  711         {{T_DIRECT, T_FIXED,
  712          "Initio  ", "",                 ""},     PQUIRK_NOBIGMODESENSE},
  713         {{T_DIRECT, T_FIXED,
  714          "JMicron ", "Generic         ", ""},     PQUIRK_NOFUA},
  715         {{T_DIRECT, T_REMOV,
  716          "MPL     ", "MC-DISK-        ", ""},     PQUIRK_NOLUNS},
  717         {{T_DIRECT, T_FIXED,
  718          "MAXTOR  ", "XT-3280         ", ""},     PQUIRK_NOLUNS},
  719         {{T_DIRECT, T_FIXED,
  720          "MAXTOR  ", "XT-4380S        ", ""},     PQUIRK_NOLUNS},
  721         {{T_DIRECT, T_FIXED,
  722          "MAXTOR  ", "MXT-1240S       ", ""},     PQUIRK_NOLUNS},
  723         {{T_DIRECT, T_FIXED,
  724          "MAXTOR  ", "XT-4170S        ", ""},     PQUIRK_NOLUNS},
  725         {{T_DIRECT, T_FIXED,
  726          "MAXTOR  ", "XT-8760S",         ""},     PQUIRK_NOLUNS},
  727         {{T_DIRECT, T_FIXED,
  728          "MAXTOR  ", "LXT-213S        ", ""},     PQUIRK_NOLUNS},
  729         {{T_DIRECT, T_FIXED,
  730          "MAXTOR  ", "LXT-213S SUN0207", ""},     PQUIRK_NOLUNS},
  731         {{T_DIRECT, T_FIXED,
  732          "MAXTOR  ", "LXT-200S        ", ""},     PQUIRK_NOLUNS},
  733         {{T_DIRECT, T_FIXED,
  734          "MEGADRV ", "EV1000",           ""},     PQUIRK_NOMODESENSE},
  735         {{T_DIRECT, T_FIXED,
  736          "MICROP", "1991-27MZ",          ""},     PQUIRK_NOTAG},
  737         {{T_DIRECT, T_FIXED,
  738          "MST     ", "SnapLink        ", ""},     PQUIRK_NOLUNS},
  739         {{T_DIRECT, T_FIXED,
  740          "NEC     ", "D3847           ", "0307"}, PQUIRK_NOLUNS},
  741         {{T_DIRECT, T_FIXED,
  742          "QUANTUM ", "ELS85S          ", ""},     PQUIRK_AUTOSAVE},
  743         {{T_DIRECT, T_FIXED,
  744          "QUANTUM ", "LPS525S         ", ""},     PQUIRK_NOLUNS},
  745         {{T_DIRECT, T_FIXED,
  746          "QUANTUM ", "P105S 910-10-94x", ""},     PQUIRK_NOLUNS},
  747         {{T_DIRECT, T_FIXED,
  748          "QUANTUM ", "PD1225S         ", ""},     PQUIRK_NOLUNS},
  749         {{T_DIRECT, T_FIXED,
  750          "QUANTUM ", "PD210S   SUN0207", ""},     PQUIRK_NOLUNS},
  751         {{T_DIRECT, T_FIXED,
  752          "QUANTUM ", "ATLAS IV 9 WLS", "0A0A"},   PQUIRK_CAP_NODT},
  753         {{T_DIRECT, T_FIXED,
  754          "RODIME  ", "RO3000S         ", ""},     PQUIRK_NOLUNS},
  755         {{T_DIRECT, T_FIXED,
  756          "SEAGATE ", "ST125N          ", ""},     PQUIRK_NOLUNS},
  757         {{T_DIRECT, T_FIXED,
  758          "SEAGATE ", "ST157N          ", ""},     PQUIRK_NOLUNS},
  759         {{T_DIRECT, T_FIXED,
  760          "SEAGATE ", "ST296           ", ""},     PQUIRK_NOLUNS},
  761         {{T_DIRECT, T_FIXED,
  762          "SEAGATE ", "ST296N          ", ""},     PQUIRK_NOLUNS},
  763         {{T_DIRECT, T_FIXED,
  764          "SEAGATE ", "ST318404LC      ", ""},     PQUIRK_NOLUNS},
  765         {{T_DIRECT, T_FIXED,
  766          "SEAGATE ", "ST336753LC      ", ""},     PQUIRK_NOLUNS},
  767         {{T_DIRECT, T_FIXED,
  768          "SEAGATE ", "ST336753LW      ", ""},     PQUIRK_NOLUNS},
  769         {{T_DIRECT, T_FIXED,
  770          "SEAGATE ", "ST336754LC      ", ""},     PQUIRK_NOLUNS},
  771         {{T_DIRECT, T_FIXED,
  772          "SEAGATE ", "ST39236LC       ", ""},     PQUIRK_NOLUNS},
  773         {{T_DIRECT, T_FIXED,
  774          "SEAGATE ", "ST15150N        ", ""},     PQUIRK_NOTAG},
  775         {{T_DIRECT, T_FIXED,
  776          "SEAGATE ", "ST19171",          ""},     PQUIRK_NOMODESENSE},
  777         {{T_DIRECT, T_FIXED,
  778          "SEAGATE ", "ST32430N",         ""},     PQUIRK_CAP_SYNC},
  779         {{T_DIRECT, T_FIXED,
  780          "SEAGATE ", "ST34501FC       ", ""},     PQUIRK_NOMODESENSE},
  781         {{T_DIRECT, T_FIXED,
  782          "SEAGATE ", "SX910800N",        ""},     PQUIRK_NOTAG},
  783         {{T_DIRECT, T_FIXED,
  784          "TOSHIBA ", "MK538FB         ", "6027"}, PQUIRK_NOLUNS},
  785         {{T_DIRECT, T_FIXED,
  786          "MICROP  ", "1924",          ""},     PQUIRK_CAP_SYNC},
  787         {{T_DIRECT, T_FIXED,
  788          "FUJITSU ", "M2266",         ""},     PQUIRK_CAP_SYNC},
  789         {{T_DIRECT, T_FIXED,
  790          "FUJITSU ", "M2624S-512      ", ""},     PQUIRK_CAP_SYNC},
  791         {{T_DIRECT, T_FIXED,
  792          "SEAGATE ", "SX336704LC"   , ""}, PQUIRK_CAP_SYNC | PQUIRK_CAP_WIDE16},
  793         {{T_DIRECT, T_FIXED,
  794          "SEAGATE ", "SX173404LC",       ""},     PQUIRK_CAP_SYNC | PQUIRK_CAP_WIDE16},
  795         {{T_DIRECT, T_FIXED,
  796          "ORACLE",   "BlockVolume",      ""},     PQUIRK_ONLYBIG},
  797 
  798         {{T_DIRECT, T_REMOV,
  799          "IOMEGA", "ZIP 100",            "J.03"}, PQUIRK_NOLUNS|PQUIRK_NOSYNC},
  800         {{T_DIRECT, T_REMOV,
  801          "INSITE", "I325VM",             ""},     PQUIRK_NOLUNS},
  802 
  803         /* XXX: QIC-36 tape behind Emulex adapter.  Very broken. */
  804         {{T_SEQUENTIAL, T_REMOV,
  805          "        ", "                ", "    "}, PQUIRK_NOLUNS},
  806         {{T_SEQUENTIAL, T_REMOV,
  807          "EMULEX  ", "MT-02 QIC       ", ""},     PQUIRK_NOLUNS},
  808         {{T_SEQUENTIAL, T_REMOV,
  809          "CALIPER ", "CP150           ", ""},     PQUIRK_NOLUNS},
  810         {{T_SEQUENTIAL, T_REMOV,
  811          "EXABYTE ", "EXB-8200        ", ""},     PQUIRK_NOLUNS},
  812         {{T_SEQUENTIAL, T_REMOV,
  813          "SONY    ", "GY-10C          ", ""},     PQUIRK_NOLUNS},
  814         {{T_SEQUENTIAL, T_REMOV,
  815          "SONY    ", "SDT-2000        ", "2.09"}, PQUIRK_NOLUNS},
  816         {{T_SEQUENTIAL, T_REMOV,
  817          "SONY    ", "SDT-5000        ", "3."},   PQUIRK_NOSYNC|PQUIRK_NOWIDE},
  818         {{T_SEQUENTIAL, T_REMOV,
  819          "SONY    ", "SDT-5200        ", "3."},   PQUIRK_NOLUNS},
  820         {{T_SEQUENTIAL, T_REMOV,
  821          "TANDBERG", " TDC 3600       ", ""},     PQUIRK_NOLUNS},
  822         /* Following entry reported as a Tandberg 3600; ref. PR1933 */
  823         {{T_SEQUENTIAL, T_REMOV,
  824          "ARCHIVE ", "VIPER 150  21247", ""},     PQUIRK_NOLUNS},
  825         /* Following entry for a Cipher ST150S; ref. PR4171 */
  826         {{T_SEQUENTIAL, T_REMOV,
  827          "ARCHIVE ", "VIPER 1500 21247", "2.2G"}, PQUIRK_NOLUNS},
  828         {{T_SEQUENTIAL, T_REMOV,
  829          "ARCHIVE ", "Python 28454-XXX", ""},     PQUIRK_NOLUNS},
  830         {{T_SEQUENTIAL, T_REMOV,
  831          "WANGTEK ", "5099ES SCSI",      ""},     PQUIRK_NOLUNS},
  832         {{T_SEQUENTIAL, T_REMOV,
  833          "WANGTEK ", "5150ES SCSI",      ""},     PQUIRK_NOLUNS},
  834         {{T_SEQUENTIAL, T_REMOV,
  835          "WANGTEK ", "SCSI-36",          ""},     PQUIRK_NOLUNS},
  836         {{T_SEQUENTIAL, T_REMOV,
  837          "WangDAT ", "Model 1300      ", "02.4"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE},
  838         {{T_SEQUENTIAL, T_REMOV,
  839          "WangDAT ", "Model 2600      ", "01.7"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE},
  840         {{T_SEQUENTIAL, T_REMOV,
  841          "WangDAT ", "Model 3200      ", "02.2"}, PQUIRK_NOSYNC|PQUIRK_NOWIDE},
  842         {{T_SEQUENTIAL, T_REMOV,
  843          "TEAC    ", "MT-2ST/N50      ", ""},     PQUIRK_NOLUNS},
  844 
  845         {{T_SCANNER, T_FIXED,
  846          "RICOH   ", "IS60            ", "1R08"}, PQUIRK_NOLUNS},
  847         {{T_SCANNER, T_FIXED,
  848          "UMAX    ", "Astra 1200S     ", "V2.9"}, PQUIRK_NOLUNS},
  849         {{T_SCANNER, T_FIXED,
  850          "UMAX    ", "Astra 1220S     ", ""},     PQUIRK_NOLUNS},
  851         {{T_SCANNER, T_FIXED,
  852          "UMAX    ", "UMAX S-6E       ", "V2.0"}, PQUIRK_NOLUNS},
  853         {{T_SCANNER, T_FIXED,
  854          "UMAX    ", "UMAX S-12       ", "V2.1"}, PQUIRK_NOLUNS},
  855         {{T_SCANNER, T_FIXED,
  856          "ULTIMA  ", "A6000C          ", ""},     PQUIRK_NOLUNS},
  857         {{T_PROCESSOR, T_FIXED,
  858          "ESG-SHV",  "SCA HSBP M15",     ""},     PQUIRK_NOLUNS},
  859         {{T_PROCESSOR, T_FIXED,
  860          "SYMBIOS",  "",                 ""},     PQUIRK_NOLUNS},
  861         {{T_PROCESSOR, T_FIXED,
  862          "LITRONIC", "PCMCIA          ", ""},     PQUIRK_NOLUNS},
  863         {{T_CHANGER, T_REMOV,
  864          "SONY    ", "CDL1100         ", ""},     PQUIRK_NOLUNS},
  865         {{T_ENCLOSURE, T_FIXED,
  866          "SUN     ", "SENA            ", ""},     PQUIRK_NOLUNS},
  867 };
  868 
  869 /*
  870  * given a target and lun, ask the device what
  871  * it is, and find the correct driver table
  872  * entry.
  873  */
  874 static int
  875 scsi_probe_device(struct scsibus_softc *sc, int target, int lun)
  876 {
  877         struct scsipi_channel *chan = sc->sc_channel;
  878         struct scsipi_periph *periph;
  879         struct scsipi_inquiry_data inqbuf;
  880         const struct scsi_quirk_inquiry_pattern *finger;
  881         int checkdtype, priority, docontinue, quirks;
  882         struct scsipibus_attach_args sa;
  883         cfdata_t cf;
  884         int locs[SCSIBUSCF_NLOCS];
  885 
  886         /*
  887          * Assume no more LUNs to search after this one.
  888          * If we successfully get Inquiry data and after
  889          * merging quirks we find we can probe for more
  890          * LUNs, we will.
  891          */
  892         docontinue = 0;
  893 
  894         /* Skip this slot if it is already attached. */
  895         if (scsipi_lookup_periph(chan, target, lun) != NULL)
  896                 return (docontinue);
  897 
  898         periph = scsipi_alloc_periph(M_WAITOK);
  899         periph->periph_channel = chan;
  900         periph->periph_switch = &scsi_probe_dev;
  901 
  902         periph->periph_target = target;
  903         periph->periph_lun = lun;
  904         periph->periph_quirks = chan->chan_defquirks;
  905 
  906 #ifdef SCSIPI_DEBUG
  907         if (SCSIPI_DEBUG_TYPE == SCSIPI_BUSTYPE_SCSI &&
  908             SCSIPI_DEBUG_TARGET == target &&
  909             SCSIPI_DEBUG_LUN == lun)
  910                 periph->periph_dbflags |= SCSIPI_DEBUG_FLAGS;
  911 #endif
  912 
  913         /*
  914          * Ask the device what it is
  915          */
  916 
  917 #ifdef SCSI_2_DEF
  918         /* some devices need to be told to go to SCSI2 */
  919         /* However some just explode if you tell them this.. leave it out */
  920         scsi_change_def(periph, XS_CTL_DISCOVERY | XS_CTL_SILENT);
  921 #endif /* SCSI_2_DEF */
  922 
  923         /* Now go ask the device all about itself. */
  924         memset(&inqbuf, 0, sizeof(inqbuf));
  925         {
  926                 u_int8_t *extension = &inqbuf.flags1;
  927                 int len = 0;
  928                 while (len < 3)
  929                         extension[len++] = '\0';
  930                 while (len < 3 + 28)
  931                         extension[len++] = ' ';
  932                 while (len < 3 + 28 + 20)
  933                         extension[len++] = '\0';
  934                 while (len < 3 + 28 + 20 + 1)
  935                         extension[len++] = '\0';
  936                 while (len < 3 + 28 + 20 + 1 + 1)
  937                         extension[len++] = '\0';
  938                 while (len < 3 + 28 + 20 + 1 + 1 + (8*2))
  939                         extension[len++] = ' ';
  940         }
  941         if (scsipi_inquire(periph, &inqbuf, XS_CTL_DISCOVERY | XS_CTL_SILENT))
  942                 goto bad;
  943 
  944         periph->periph_type = inqbuf.device & SID_TYPE;
  945         if (inqbuf.dev_qual2 & SID_REMOVABLE)
  946                 periph->periph_flags |= PERIPH_REMOVABLE;
  947         periph->periph_version = inqbuf.version & SID_ANSII;
  948 
  949         /*
  950          * Any device qualifier that has the top bit set (qualifier&4 != 0)
  951          * is vendor specific and won't match in this switch.
  952          * All we do here is throw out bad/negative responses.
  953          */
  954         checkdtype = 0;
  955         switch (inqbuf.device & SID_QUAL) {
  956         case SID_QUAL_LU_PRESENT:
  957                 checkdtype = 1;
  958                 break;
  959 
  960         case SID_QUAL_LU_NOTPRESENT:
  961         case SID_QUAL_reserved:
  962         case SID_QUAL_LU_NOT_SUPP:
  963                 goto bad;
  964 
  965         default:
  966                 break;
  967         }
  968 
  969         /* Let the adapter driver handle the device separately if it wants. */
  970         if (chan->chan_adapter->adapt_accesschk != NULL &&
  971             (*chan->chan_adapter->adapt_accesschk)(periph, &sa.sa_inqbuf))
  972                 goto bad;
  973 
  974         if (checkdtype) {
  975                 switch (periph->periph_type) {
  976                 case T_DIRECT:
  977                 case T_SEQUENTIAL:
  978                 case T_PRINTER:
  979                 case T_PROCESSOR:
  980                 case T_WORM:
  981                 case T_CDROM:
  982                 case T_SCANNER:
  983                 case T_OPTICAL:
  984                 case T_CHANGER:
  985                 case T_COMM:
  986                 case T_IT8_1:
  987                 case T_IT8_2:
  988                 case T_STORARRAY:
  989                 case T_ENCLOSURE:
  990                 case T_SIMPLE_DIRECT:
  991                 case T_OPTIC_CARD_RW:
  992                 case T_OBJECT_STORED:
  993                 default:
  994                         break;
  995                 case T_NODEVICE:
  996                         goto bad;
  997                 }
  998         }
  999 
 1000         sa.sa_periph = periph;
 1001         sa.sa_inqbuf.type = inqbuf.device;
 1002         sa.sa_inqbuf.removable = inqbuf.dev_qual2 & SID_REMOVABLE ?
 1003             T_REMOV : T_FIXED;
 1004         sa.sa_inqbuf.vendor = inqbuf.vendor;
 1005         sa.sa_inqbuf.product = inqbuf.product;
 1006         sa.sa_inqbuf.revision = inqbuf.revision;
 1007         sa.scsipi_info.scsi_version = inqbuf.version;
 1008         sa.sa_inqptr = &inqbuf;
 1009 
 1010         finger = scsipi_inqmatch(
 1011             &sa.sa_inqbuf, scsi_quirk_patterns,
 1012             sizeof(scsi_quirk_patterns)/sizeof(scsi_quirk_patterns[0]),
 1013             sizeof(scsi_quirk_patterns[0]), &priority);
 1014 
 1015         if (finger != NULL)
 1016                 quirks = finger->quirks;
 1017         else
 1018                 quirks = 0;
 1019 
 1020         /*
 1021          * Determine the operating mode capabilities of the device.
 1022          */
 1023         if (periph->periph_version >= 2) {
 1024                 if ((inqbuf.flags3 & SID_CmdQue) != 0 &&
 1025                     (quirks & PQUIRK_NOTAG) == 0)
 1026                         periph->periph_cap |= PERIPH_CAP_TQING;
 1027                 if ((inqbuf.flags3 & SID_Linked) != 0)
 1028                         periph->periph_cap |= PERIPH_CAP_LINKCMDS;
 1029                 if ((inqbuf.flags3 & SID_Sync) != 0 &&
 1030                     (quirks & PQUIRK_NOSYNC) == 0)
 1031                         periph->periph_cap |= PERIPH_CAP_SYNC;
 1032                 if ((inqbuf.flags3 & SID_WBus16) != 0 &&
 1033                     (quirks & PQUIRK_NOWIDE) == 0)
 1034                         periph->periph_cap |= PERIPH_CAP_WIDE16;
 1035                 if ((inqbuf.flags3 & SID_WBus32) != 0 &&
 1036                     (quirks & PQUIRK_NOWIDE) == 0)
 1037                         periph->periph_cap |= PERIPH_CAP_WIDE32;
 1038                 if ((inqbuf.flags3 & SID_SftRe) != 0)
 1039                         periph->periph_cap |= PERIPH_CAP_SFTRESET;
 1040                 if ((inqbuf.flags3 & SID_RelAdr) != 0)
 1041                         periph->periph_cap |= PERIPH_CAP_RELADR;
 1042                 /* SPC-2 */
 1043                 if (periph->periph_version >= 3 &&
 1044                     !(quirks & PQUIRK_CAP_NODT)){
 1045                         /*
 1046                          * Report ST clocking though CAP_WIDExx/CAP_SYNC.
 1047                          * If the device only supports DT, clear these
 1048                          * flags (DT implies SYNC and WIDE)
 1049                          */
 1050                         switch (inqbuf.flags4 & SID_Clocking) {
 1051                         case SID_CLOCKING_DT_ONLY:
 1052                                 periph->periph_cap &=
 1053                                     ~(PERIPH_CAP_SYNC |
 1054                                       PERIPH_CAP_WIDE16 |
 1055                                       PERIPH_CAP_WIDE32);
 1056                                 /* FALLTHROUGH */
 1057                         case SID_CLOCKING_SD_DT:
 1058                                 periph->periph_cap |= PERIPH_CAP_DT;
 1059                                 break;
 1060                         default: /* ST only or invalid */
 1061                                 /* nothing to do */
 1062                                 break;
 1063                         }
 1064                 }
 1065                 if (periph->periph_version >= 3) {
 1066                         if (inqbuf.flags4 & SID_IUS)
 1067                                 periph->periph_cap |= PERIPH_CAP_IUS;
 1068                         if (inqbuf.flags4 & SID_QAS)
 1069                                 periph->periph_cap |= PERIPH_CAP_QAS;
 1070                 }
 1071         }
 1072         if (quirks & PQUIRK_CAP_SYNC)
 1073                 periph->periph_cap |= PERIPH_CAP_SYNC;
 1074         if (quirks & PQUIRK_CAP_WIDE16)
 1075                 periph->periph_cap |= PERIPH_CAP_WIDE16;
 1076 
 1077         /*
 1078          * Now apply any quirks from the table.
 1079          */
 1080         periph->periph_quirks |= quirks;
 1081         if (periph->periph_version == 0 &&
 1082             (periph->periph_quirks & PQUIRK_FORCELUNS) == 0)
 1083                 periph->periph_quirks |= PQUIRK_NOLUNS;
 1084 
 1085         if ((periph->periph_quirks & PQUIRK_NOLUNS) == 0)
 1086                 docontinue = 1;
 1087 
 1088         locs[SCSIBUSCF_TARGET] = target;
 1089         locs[SCSIBUSCF_LUN] = lun;
 1090 
 1091         KERNEL_LOCK(1, NULL);
 1092         if ((cf = config_search(sc->sc_dev, &sa,
 1093                                 CFARGS(.submatch = config_stdsubmatch,
 1094                                        .locators = locs))) != NULL) {
 1095                 scsipi_insert_periph(chan, periph);
 1096 
 1097                 /*
 1098                  * Determine supported opcodes and timeouts if available.
 1099                  * Only do this on peripherals reporting SCSI version 3
 1100                  * or greater - this command isn't in the SCSI-2 spec. and
 1101                  * it causes either timeouts or peripherals disappearing
 1102                  * when sent to some SCSI-1 or SCSI-2 peripherals.
 1103                  */
 1104                 if (periph->periph_version >= 3)
 1105                         scsipi_get_opcodeinfo(periph);
 1106 
 1107                 /*
 1108                  * XXX Can't assign periph_dev here, because we'll
 1109                  * XXX need it before config_attach() returns.  Must
 1110                  * XXX assign it in periph driver.
 1111                  */
 1112                 config_attach(sc->sc_dev, cf, &sa, scsibusprint,
 1113                     CFARGS(.locators = locs));
 1114                 KERNEL_UNLOCK_ONE(NULL);
 1115         } else {
 1116                 scsibusprint(&sa, device_xname(sc->sc_dev));
 1117                 aprint_normal(" not configured\n");
 1118                 KERNEL_UNLOCK_ONE(NULL);
 1119                 goto bad;
 1120         }
 1121 
 1122         return (docontinue);
 1123 
 1124 bad:
 1125         scsipi_free_periph(periph);
 1126         return (docontinue);
 1127 }
 1128 
 1129 /****** Entry points for user control of the SCSI bus. ******/
 1130 
 1131 static int
 1132 scsibusopen(dev_t dev, int flag, int fmt,
 1133     struct lwp *l)
 1134 {
 1135         struct scsibus_softc *sc;
 1136         int error, unit = minor(dev);
 1137 
 1138         sc = device_lookup_private(&scsibus_cd, unit);
 1139         if (sc == NULL)
 1140                 return (ENXIO);
 1141 
 1142         if (sc->sc_flags & SCSIBUSF_OPEN)
 1143                 return (EBUSY);
 1144 
 1145         if ((error = scsipi_adapter_addref(sc->sc_channel->chan_adapter)) != 0)
 1146                 return (error);
 1147 
 1148         sc->sc_flags |= SCSIBUSF_OPEN;
 1149 
 1150         return (0);
 1151 }
 1152 
 1153 static int
 1154 scsibusclose(dev_t dev, int flag, int fmt,
 1155     struct lwp *l)
 1156 {
 1157         struct scsibus_softc *sc;
 1158 
 1159         sc = device_lookup_private(&scsibus_cd, minor(dev));
 1160         scsipi_adapter_delref(sc->sc_channel->chan_adapter);
 1161 
 1162         sc->sc_flags &= ~SCSIBUSF_OPEN;
 1163 
 1164         return (0);
 1165 }
 1166 
 1167 static int
 1168 scsibusioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
 1169 {
 1170         struct scsibus_softc *sc;
 1171         struct scsipi_channel *chan;
 1172         int error;
 1173 
 1174         sc = device_lookup_private(&scsibus_cd, minor(dev));
 1175         chan = sc->sc_channel;
 1176 
 1177         /*
 1178          * Enforce write permission for ioctls that change the
 1179          * state of the bus.  Host adapter specific ioctls must
 1180          * be checked by the adapter driver.
 1181          */
 1182         switch (cmd) {
 1183         case SCBUSIOSCAN:
 1184         case SCBUSIODETACH:
 1185         case SCBUSIORESET:
 1186                 if ((flag & FWRITE) == 0)
 1187                         return (EBADF);
 1188         }
 1189 
 1190         switch (cmd) {
 1191         case SCBUSIOSCAN:
 1192             {
 1193                 struct scbusioscan_args *a =
 1194                     (struct scbusioscan_args *)addr;
 1195 
 1196                 error = scsi_probe_bus(sc, a->sa_target, a->sa_lun);
 1197                 break;
 1198             }
 1199 
 1200         case SCBUSIODETACH:
 1201             {
 1202                 struct scbusiodetach_args *a =
 1203                     (struct scbusiodetach_args *)addr;
 1204 
 1205                 error = scsipi_target_detach(chan, a->sa_target, a->sa_lun, 0);
 1206                 break;
 1207             }
 1208 
 1209 
 1210         case SCBUSIORESET:
 1211                 /* FALLTHROUGH */
 1212         default:
 1213                 error = scsipi_adapter_ioctl(chan, cmd, addr, flag, l->l_proc);
 1214                 break;
 1215         }
 1216 
 1217         return (error);
 1218 }

Cache object: 9f56d4fcb22b588354396f76c7756faa


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