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/scsipi_base.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: scsipi_base.c,v 1.148 2008/05/11 05:17:23 mlelstv Exp $        */
    2 
    3 /*-
    4  * Copyright (c) 1998, 1999, 2000, 2002, 2003, 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; by 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 #include <sys/cdefs.h>
   34 __KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.148 2008/05/11 05:17:23 mlelstv Exp $");
   35 
   36 #include "opt_scsi.h"
   37 
   38 #include <sys/param.h>
   39 #include <sys/systm.h>
   40 #include <sys/kernel.h>
   41 #include <sys/buf.h>
   42 #include <sys/uio.h>
   43 #include <sys/malloc.h>
   44 #include <sys/pool.h>
   45 #include <sys/errno.h>
   46 #include <sys/device.h>
   47 #include <sys/proc.h>
   48 #include <sys/kthread.h>
   49 #include <sys/hash.h>
   50 
   51 #include <uvm/uvm_extern.h>
   52 
   53 #include <dev/scsipi/scsi_spc.h>
   54 #include <dev/scsipi/scsipi_all.h>
   55 #include <dev/scsipi/scsipi_disk.h>
   56 #include <dev/scsipi/scsipiconf.h>
   57 #include <dev/scsipi/scsipi_base.h>
   58 
   59 #include <dev/scsipi/scsi_all.h>
   60 #include <dev/scsipi/scsi_message.h>
   61 
   62 static int      scsipi_complete(struct scsipi_xfer *);
   63 static void     scsipi_request_sense(struct scsipi_xfer *);
   64 static int      scsipi_enqueue(struct scsipi_xfer *);
   65 static void     scsipi_run_queue(struct scsipi_channel *chan);
   66 
   67 static void     scsipi_completion_thread(void *);
   68 
   69 static void     scsipi_get_tag(struct scsipi_xfer *);
   70 static void     scsipi_put_tag(struct scsipi_xfer *);
   71 
   72 static int      scsipi_get_resource(struct scsipi_channel *);
   73 static void     scsipi_put_resource(struct scsipi_channel *);
   74 
   75 static void     scsipi_async_event_max_openings(struct scsipi_channel *,
   76                     struct scsipi_max_openings *);
   77 static void     scsipi_async_event_xfer_mode(struct scsipi_channel *,
   78                     struct scsipi_xfer_mode *);
   79 static void     scsipi_async_event_channel_reset(struct scsipi_channel *);
   80 
   81 static struct pool scsipi_xfer_pool;
   82 
   83 /*
   84  * scsipi_init:
   85  *
   86  *      Called when a scsibus or atapibus is attached to the system
   87  *      to initialize shared data structures.
   88  */
   89 void
   90 scsipi_init(void)
   91 {
   92         static int scsipi_init_done;
   93 
   94         if (scsipi_init_done)
   95                 return;
   96         scsipi_init_done = 1;
   97 
   98         /* Initialize the scsipi_xfer pool. */
   99         pool_init(&scsipi_xfer_pool, sizeof(struct scsipi_xfer), 0,
  100             0, 0, "scxspl", NULL, IPL_BIO);
  101         if (pool_prime(&scsipi_xfer_pool,
  102             PAGE_SIZE / sizeof(struct scsipi_xfer)) == ENOMEM) {
  103                 printf("WARNING: not enough memory for scsipi_xfer_pool\n");
  104         }
  105 }
  106 
  107 /*
  108  * scsipi_channel_init:
  109  *
  110  *      Initialize a scsipi_channel when it is attached.
  111  */
  112 int
  113 scsipi_channel_init(struct scsipi_channel *chan)
  114 {
  115         struct scsipi_adapter *adapt = chan->chan_adapter;
  116         int i;
  117 
  118         /* Initialize shared data. */
  119         scsipi_init();
  120 
  121         /* Initialize the queues. */
  122         TAILQ_INIT(&chan->chan_queue);
  123         TAILQ_INIT(&chan->chan_complete);
  124 
  125         for (i = 0; i < SCSIPI_CHAN_PERIPH_BUCKETS; i++)
  126                 LIST_INIT(&chan->chan_periphtab[i]);
  127 
  128         /*
  129          * Create the asynchronous completion thread.
  130          */
  131         if (kthread_create(PRI_NONE, 0, NULL, scsipi_completion_thread, chan,
  132             &chan->chan_thread, "%s", chan->chan_name)) {
  133                 aprint_error_dev(adapt->adapt_dev, "unable to create completion thread for "
  134                     "channel %d\n", chan->chan_channel);
  135                 panic("scsipi_channel_init");
  136         }
  137 
  138         return (0);
  139 }
  140 
  141 /*
  142  * scsipi_channel_shutdown:
  143  *
  144  *      Shutdown a scsipi_channel.
  145  */
  146 void
  147 scsipi_channel_shutdown(struct scsipi_channel *chan)
  148 {
  149 
  150         /*
  151          * Shut down the completion thread.
  152          */
  153         chan->chan_tflags |= SCSIPI_CHANT_SHUTDOWN;
  154         wakeup(&chan->chan_complete);
  155 
  156         /*
  157          * Now wait for the thread to exit.
  158          */
  159         while (chan->chan_thread != NULL)
  160                 (void) tsleep(&chan->chan_thread, PRIBIO, "scshut", 0);
  161 }
  162 
  163 static uint32_t
  164 scsipi_chan_periph_hash(uint64_t t, uint64_t l)
  165 {
  166         uint32_t hash;
  167 
  168         hash = hash32_buf(&t, sizeof(t), HASH32_BUF_INIT);
  169         hash = hash32_buf(&l, sizeof(l), hash);
  170 
  171         return (hash & SCSIPI_CHAN_PERIPH_HASHMASK);
  172 }
  173 
  174 /*
  175  * scsipi_insert_periph:
  176  *
  177  *      Insert a periph into the channel.
  178  */
  179 void
  180 scsipi_insert_periph(struct scsipi_channel *chan, struct scsipi_periph *periph)
  181 {
  182         uint32_t hash;
  183         int s;
  184 
  185         hash = scsipi_chan_periph_hash(periph->periph_target,
  186             periph->periph_lun);
  187 
  188         s = splbio();
  189         LIST_INSERT_HEAD(&chan->chan_periphtab[hash], periph, periph_hash);
  190         splx(s);
  191 }
  192 
  193 /*
  194  * scsipi_remove_periph:
  195  *
  196  *      Remove a periph from the channel.
  197  */
  198 void
  199 scsipi_remove_periph(struct scsipi_channel *chan,
  200     struct scsipi_periph *periph)
  201 {
  202         int s;
  203 
  204         s = splbio();
  205         LIST_REMOVE(periph, periph_hash);
  206         splx(s);
  207 }
  208 
  209 /*
  210  * scsipi_lookup_periph:
  211  *
  212  *      Lookup a periph on the specified channel.
  213  */
  214 struct scsipi_periph *
  215 scsipi_lookup_periph(struct scsipi_channel *chan, int target, int lun)
  216 {
  217         struct scsipi_periph *periph;
  218         uint32_t hash;
  219         int s;
  220 
  221         if (target >= chan->chan_ntargets ||
  222             lun >= chan->chan_nluns)
  223                 return (NULL);
  224 
  225         hash = scsipi_chan_periph_hash(target, lun);
  226 
  227         s = splbio();
  228         LIST_FOREACH(periph, &chan->chan_periphtab[hash], periph_hash) {
  229                 if (periph->periph_target == target &&
  230                     periph->periph_lun == lun)
  231                         break;
  232         }
  233         splx(s);
  234 
  235         return (periph);
  236 }
  237 
  238 /*
  239  * scsipi_get_resource:
  240  *
  241  *      Allocate a single xfer `resource' from the channel.
  242  *
  243  *      NOTE: Must be called at splbio().
  244  */
  245 static int
  246 scsipi_get_resource(struct scsipi_channel *chan)
  247 {
  248         struct scsipi_adapter *adapt = chan->chan_adapter;
  249 
  250         if (chan->chan_flags & SCSIPI_CHAN_OPENINGS) {
  251                 if (chan->chan_openings > 0) {
  252                         chan->chan_openings--;
  253                         return (1);
  254                 }
  255                 return (0);
  256         }
  257 
  258         if (adapt->adapt_openings > 0) {
  259                 adapt->adapt_openings--;
  260                 return (1);
  261         }
  262         return (0);
  263 }
  264 
  265 /*
  266  * scsipi_grow_resources:
  267  *
  268  *      Attempt to grow resources for a channel.  If this succeeds,
  269  *      we allocate one for our caller.
  270  *
  271  *      NOTE: Must be called at splbio().
  272  */
  273 static inline int
  274 scsipi_grow_resources(struct scsipi_channel *chan)
  275 {
  276 
  277         if (chan->chan_flags & SCSIPI_CHAN_CANGROW) {
  278                 if ((chan->chan_flags & SCSIPI_CHAN_TACTIVE) == 0) {
  279                         scsipi_adapter_request(chan,
  280                             ADAPTER_REQ_GROW_RESOURCES, NULL);
  281                         return (scsipi_get_resource(chan));
  282                 }
  283                 /*
  284                  * ask the channel thread to do it. It'll have to thaw the
  285                  * queue
  286                  */
  287                 scsipi_channel_freeze(chan, 1);
  288                 chan->chan_tflags |= SCSIPI_CHANT_GROWRES;
  289                 wakeup(&chan->chan_complete);
  290                 return (0);
  291         }
  292 
  293         return (0);
  294 }
  295 
  296 /*
  297  * scsipi_put_resource:
  298  *
  299  *      Free a single xfer `resource' to the channel.
  300  *
  301  *      NOTE: Must be called at splbio().
  302  */
  303 static void
  304 scsipi_put_resource(struct scsipi_channel *chan)
  305 {
  306         struct scsipi_adapter *adapt = chan->chan_adapter;
  307 
  308         if (chan->chan_flags & SCSIPI_CHAN_OPENINGS)
  309                 chan->chan_openings++;
  310         else
  311                 adapt->adapt_openings++;
  312 }
  313 
  314 /*
  315  * scsipi_get_tag:
  316  *
  317  *      Get a tag ID for the specified xfer.
  318  *
  319  *      NOTE: Must be called at splbio().
  320  */
  321 static void
  322 scsipi_get_tag(struct scsipi_xfer *xs)
  323 {
  324         struct scsipi_periph *periph = xs->xs_periph;
  325         int bit, tag;
  326         u_int word;
  327 
  328         bit = 0;        /* XXX gcc */
  329         for (word = 0; word < PERIPH_NTAGWORDS; word++) {
  330                 bit = ffs(periph->periph_freetags[word]);
  331                 if (bit != 0)
  332                         break;
  333         }
  334 #ifdef DIAGNOSTIC
  335         if (word == PERIPH_NTAGWORDS) {
  336                 scsipi_printaddr(periph);
  337                 printf("no free tags\n");
  338                 panic("scsipi_get_tag");
  339         }
  340 #endif
  341 
  342         bit -= 1;
  343         periph->periph_freetags[word] &= ~(1 << bit);
  344         tag = (word << 5) | bit;
  345 
  346         /* XXX Should eventually disallow this completely. */
  347         if (tag >= periph->periph_openings) {
  348                 scsipi_printaddr(periph);
  349                 printf("WARNING: tag %d greater than available openings %d\n",
  350                     tag, periph->periph_openings);
  351         }
  352 
  353         xs->xs_tag_id = tag;
  354 }
  355 
  356 /*
  357  * scsipi_put_tag:
  358  *
  359  *      Put the tag ID for the specified xfer back into the pool.
  360  *
  361  *      NOTE: Must be called at splbio().
  362  */
  363 static void
  364 scsipi_put_tag(struct scsipi_xfer *xs)
  365 {
  366         struct scsipi_periph *periph = xs->xs_periph;
  367         int word, bit;
  368 
  369         word = xs->xs_tag_id >> 5;
  370         bit = xs->xs_tag_id & 0x1f;
  371 
  372         periph->periph_freetags[word] |= (1 << bit);
  373 }
  374 
  375 /*
  376  * scsipi_get_xs:
  377  *
  378  *      Allocate an xfer descriptor and associate it with the
  379  *      specified peripherial.  If the peripherial has no more
  380  *      available command openings, we either block waiting for
  381  *      one to become available, or fail.
  382  */
  383 struct scsipi_xfer *
  384 scsipi_get_xs(struct scsipi_periph *periph, int flags)
  385 {
  386         struct scsipi_xfer *xs;
  387         int s;
  388 
  389         SC_DEBUG(periph, SCSIPI_DB3, ("scsipi_get_xs\n"));
  390 
  391         KASSERT(!cold);
  392 
  393 #ifdef DIAGNOSTIC
  394         /*
  395          * URGENT commands can never be ASYNC.
  396          */
  397         if ((flags & (XS_CTL_URGENT|XS_CTL_ASYNC)) ==
  398             (XS_CTL_URGENT|XS_CTL_ASYNC)) {
  399                 scsipi_printaddr(periph);
  400                 printf("URGENT and ASYNC\n");
  401                 panic("scsipi_get_xs");
  402         }
  403 #endif
  404 
  405         s = splbio();
  406         /*
  407          * Wait for a command opening to become available.  Rules:
  408          *
  409          *      - All xfers must wait for an available opening.
  410          *        Exception: URGENT xfers can proceed when
  411          *        active == openings, because we use the opening
  412          *        of the command we're recovering for.
  413          *      - if the periph has sense pending, only URGENT & REQSENSE
  414          *        xfers may proceed.
  415          *
  416          *      - If the periph is recovering, only URGENT xfers may
  417          *        proceed.
  418          *
  419          *      - If the periph is currently executing a recovery
  420          *        command, URGENT commands must block, because only
  421          *        one recovery command can execute at a time.
  422          */
  423         for (;;) {
  424                 if (flags & XS_CTL_URGENT) {
  425                         if (periph->periph_active > periph->periph_openings)
  426                                 goto wait_for_opening;
  427                         if (periph->periph_flags & PERIPH_SENSE) {
  428                                 if ((flags & XS_CTL_REQSENSE) == 0)
  429                                         goto wait_for_opening;
  430                         } else {
  431                                 if ((periph->periph_flags &
  432                                     PERIPH_RECOVERY_ACTIVE) != 0)
  433                                         goto wait_for_opening;
  434                                 periph->periph_flags |= PERIPH_RECOVERY_ACTIVE;
  435                         }
  436                         break;
  437                 }
  438                 if (periph->periph_active >= periph->periph_openings ||
  439                     (periph->periph_flags & PERIPH_RECOVERING) != 0)
  440                         goto wait_for_opening;
  441                 periph->periph_active++;
  442                 break;
  443 
  444  wait_for_opening:
  445                 if (flags & XS_CTL_NOSLEEP) {
  446                         splx(s);
  447                         return (NULL);
  448                 }
  449                 SC_DEBUG(periph, SCSIPI_DB3, ("sleeping\n"));
  450                 periph->periph_flags |= PERIPH_WAITING;
  451                 (void) tsleep(periph, PRIBIO, "getxs", 0);
  452         }
  453         SC_DEBUG(periph, SCSIPI_DB3, ("calling pool_get\n"));
  454         xs = pool_get(&scsipi_xfer_pool,
  455             ((flags & XS_CTL_NOSLEEP) != 0 ? PR_NOWAIT : PR_WAITOK));
  456         if (xs == NULL) {
  457                 if (flags & XS_CTL_URGENT) {
  458                         if ((flags & XS_CTL_REQSENSE) == 0)
  459                                 periph->periph_flags &= ~PERIPH_RECOVERY_ACTIVE;
  460                 } else
  461                         periph->periph_active--;
  462                 scsipi_printaddr(periph);
  463                 printf("unable to allocate %sscsipi_xfer\n",
  464                     (flags & XS_CTL_URGENT) ? "URGENT " : "");
  465         }
  466         splx(s);
  467 
  468         SC_DEBUG(periph, SCSIPI_DB3, ("returning\n"));
  469 
  470         if (xs != NULL) {
  471                 memset(xs, 0, sizeof(*xs));
  472                 callout_init(&xs->xs_callout, 0);
  473                 xs->xs_periph = periph;
  474                 xs->xs_control = flags;
  475                 xs->xs_status = 0;
  476                 s = splbio();
  477                 TAILQ_INSERT_TAIL(&periph->periph_xferq, xs, device_q);
  478                 splx(s);
  479         }
  480         return (xs);
  481 }
  482 
  483 /*
  484  * scsipi_put_xs:
  485  *
  486  *      Release an xfer descriptor, decreasing the outstanding command
  487  *      count for the peripherial.  If there is a thread waiting for
  488  *      an opening, wake it up.  If not, kick any queued I/O the
  489  *      peripherial may have.
  490  *
  491  *      NOTE: Must be called at splbio().
  492  */
  493 void
  494 scsipi_put_xs(struct scsipi_xfer *xs)
  495 {
  496         struct scsipi_periph *periph = xs->xs_periph;
  497         int flags = xs->xs_control;
  498 
  499         SC_DEBUG(periph, SCSIPI_DB3, ("scsipi_free_xs\n"));
  500 
  501         TAILQ_REMOVE(&periph->periph_xferq, xs, device_q);
  502         pool_put(&scsipi_xfer_pool, xs);
  503 
  504 #ifdef DIAGNOSTIC
  505         if ((periph->periph_flags & PERIPH_RECOVERY_ACTIVE) != 0 &&
  506             periph->periph_active == 0) {
  507                 scsipi_printaddr(periph);
  508                 printf("recovery without a command to recovery for\n");
  509                 panic("scsipi_put_xs");
  510         }
  511 #endif
  512 
  513         if (flags & XS_CTL_URGENT) {
  514                 if ((flags & XS_CTL_REQSENSE) == 0)
  515                         periph->periph_flags &= ~PERIPH_RECOVERY_ACTIVE;
  516         } else
  517                 periph->periph_active--;
  518         if (periph->periph_active == 0 &&
  519             (periph->periph_flags & PERIPH_WAITDRAIN) != 0) {
  520                 periph->periph_flags &= ~PERIPH_WAITDRAIN;
  521                 wakeup(&periph->periph_active);
  522         }
  523 
  524         if (periph->periph_flags & PERIPH_WAITING) {
  525                 periph->periph_flags &= ~PERIPH_WAITING;
  526                 wakeup(periph);
  527         } else {
  528                 if (periph->periph_switch->psw_start != NULL &&
  529                     device_is_active(periph->periph_dev)) {
  530                         SC_DEBUG(periph, SCSIPI_DB2,
  531                             ("calling private start()\n"));
  532                         (*periph->periph_switch->psw_start)(periph);
  533                 }
  534         }
  535 }
  536 
  537 /*
  538  * scsipi_channel_freeze:
  539  *
  540  *      Freeze a channel's xfer queue.
  541  */
  542 void
  543 scsipi_channel_freeze(struct scsipi_channel *chan, int count)
  544 {
  545         int s;
  546 
  547         s = splbio();
  548         chan->chan_qfreeze += count;
  549         splx(s);
  550 }
  551 
  552 /*
  553  * scsipi_channel_thaw:
  554  *
  555  *      Thaw a channel's xfer queue.
  556  */
  557 void
  558 scsipi_channel_thaw(struct scsipi_channel *chan, int count)
  559 {
  560         int s;
  561 
  562         s = splbio();
  563         chan->chan_qfreeze -= count;
  564         /*
  565          * Don't let the freeze count go negative.
  566          *
  567          * Presumably the adapter driver could keep track of this,
  568          * but it might just be easier to do this here so as to allow
  569          * multiple callers, including those outside the adapter driver.
  570          */
  571         if (chan->chan_qfreeze < 0) {
  572                 chan->chan_qfreeze = 0;
  573         }
  574         splx(s);
  575         /*
  576          * Kick the channel's queue here.  Note, we may be running in
  577          * interrupt context (softclock or HBA's interrupt), so the adapter
  578          * driver had better not sleep.
  579          */
  580         if (chan->chan_qfreeze == 0)
  581                 scsipi_run_queue(chan);
  582 }
  583 
  584 /*
  585  * scsipi_channel_timed_thaw:
  586  *
  587  *      Thaw a channel after some time has expired. This will also
  588  *      run the channel's queue if the freeze count has reached 0.
  589  */
  590 void
  591 scsipi_channel_timed_thaw(void *arg)
  592 {
  593         struct scsipi_channel *chan = arg;
  594 
  595         scsipi_channel_thaw(chan, 1);
  596 }
  597 
  598 /*
  599  * scsipi_periph_freeze:
  600  *
  601  *      Freeze a device's xfer queue.
  602  */
  603 void
  604 scsipi_periph_freeze(struct scsipi_periph *periph, int count)
  605 {
  606         int s;
  607 
  608         s = splbio();
  609         periph->periph_qfreeze += count;
  610         splx(s);
  611 }
  612 
  613 /*
  614  * scsipi_periph_thaw:
  615  *
  616  *      Thaw a device's xfer queue.
  617  */
  618 void
  619 scsipi_periph_thaw(struct scsipi_periph *periph, int count)
  620 {
  621         int s;
  622 
  623         s = splbio();
  624         periph->periph_qfreeze -= count;
  625 #ifdef DIAGNOSTIC
  626         if (periph->periph_qfreeze < 0) {
  627                 static const char pc[] = "periph freeze count < 0";
  628                 scsipi_printaddr(periph);
  629                 printf("%s\n", pc);
  630                 panic(pc);
  631         }
  632 #endif
  633         if (periph->periph_qfreeze == 0 &&
  634             (periph->periph_flags & PERIPH_WAITING) != 0)
  635                 wakeup(periph);
  636         splx(s);
  637 }
  638 
  639 /*
  640  * scsipi_periph_timed_thaw:
  641  *
  642  *      Thaw a device after some time has expired.
  643  */
  644 void
  645 scsipi_periph_timed_thaw(void *arg)
  646 {
  647         int s;
  648         struct scsipi_periph *periph = arg;
  649 
  650         callout_stop(&periph->periph_callout);
  651 
  652         s = splbio();
  653         scsipi_periph_thaw(periph, 1);
  654         if ((periph->periph_channel->chan_flags & SCSIPI_CHAN_TACTIVE) == 0) {
  655                 /*
  656                  * Kick the channel's queue here.  Note, we're running in
  657                  * interrupt context (softclock), so the adapter driver
  658                  * had better not sleep.
  659                  */
  660                 scsipi_run_queue(periph->periph_channel);
  661         } else {
  662                 /*
  663                  * Tell the completion thread to kick the channel's queue here.
  664                  */
  665                 periph->periph_channel->chan_tflags |= SCSIPI_CHANT_KICK;
  666                 wakeup(&periph->periph_channel->chan_complete);
  667         }
  668         splx(s);
  669 }
  670 
  671 /*
  672  * scsipi_wait_drain:
  673  *
  674  *      Wait for a periph's pending xfers to drain.
  675  */
  676 void
  677 scsipi_wait_drain(struct scsipi_periph *periph)
  678 {
  679         int s;
  680 
  681         s = splbio();
  682         while (periph->periph_active != 0) {
  683                 periph->periph_flags |= PERIPH_WAITDRAIN;
  684                 (void) tsleep(&periph->periph_active, PRIBIO, "sxdrn", 0);
  685         }
  686         splx(s);
  687 }
  688 
  689 /*
  690  * scsipi_kill_pending:
  691  *
  692  *      Kill off all pending xfers for a periph.
  693  *
  694  *      NOTE: Must be called at splbio().
  695  */
  696 void
  697 scsipi_kill_pending(struct scsipi_periph *periph)
  698 {
  699 
  700         (*periph->periph_channel->chan_bustype->bustype_kill_pending)(periph);
  701         scsipi_wait_drain(periph);
  702 }
  703 
  704 /*
  705  * scsipi_print_cdb:
  706  * prints a command descriptor block (for debug purpose, error messages,
  707  * SCSIPI_VERBOSE, ...)
  708  */
  709 void
  710 scsipi_print_cdb(struct scsipi_generic *cmd)
  711 {
  712         int i, j;
  713 
  714         printf("0x%02x", cmd->opcode);
  715 
  716         switch (CDB_GROUPID(cmd->opcode)) {
  717         case CDB_GROUPID_0:
  718                 j = CDB_GROUP0;
  719                 break;
  720         case CDB_GROUPID_1:
  721                 j = CDB_GROUP1;
  722                 break;
  723         case CDB_GROUPID_2:
  724                 j = CDB_GROUP2;
  725                 break;
  726         case CDB_GROUPID_3:
  727                 j = CDB_GROUP3;
  728                 break;
  729         case CDB_GROUPID_4:
  730                 j = CDB_GROUP4;
  731                 break;
  732         case CDB_GROUPID_5:
  733                 j = CDB_GROUP5;
  734                 break;
  735         case CDB_GROUPID_6:
  736                 j = CDB_GROUP6;
  737                 break;
  738         case CDB_GROUPID_7:
  739                 j = CDB_GROUP7;
  740                 break;
  741         default:
  742                 j = 0;
  743         }
  744         if (j == 0)
  745                 j = sizeof (cmd->bytes);
  746         for (i = 0; i < j-1; i++) /* already done the opcode */
  747                 printf(" %02x", cmd->bytes[i]);
  748 }
  749 
  750 /*
  751  * scsipi_interpret_sense:
  752  *
  753  *      Look at the returned sense and act on the error, determining
  754  *      the unix error number to pass back.  (0 = report no error)
  755  *
  756  *      NOTE: If we return ERESTART, we are expected to haved
  757  *      thawed the device!
  758  *
  759  *      THIS IS THE DEFAULT ERROR HANDLER FOR SCSI DEVICES.
  760  */
  761 int
  762 scsipi_interpret_sense(struct scsipi_xfer *xs)
  763 {
  764         struct scsi_sense_data *sense;
  765         struct scsipi_periph *periph = xs->xs_periph;
  766         u_int8_t key;
  767         int error;
  768 #ifndef SCSIVERBOSE
  769         u_int32_t info;
  770         static const char *error_mes[] = {
  771                 "soft error (corrected)",
  772                 "not ready", "medium error",
  773                 "non-media hardware failure", "illegal request",
  774                 "unit attention", "readonly device",
  775                 "no data found", "vendor unique",
  776                 "copy aborted", "command aborted",
  777                 "search returned equal", "volume overflow",
  778                 "verify miscompare", "unknown error key"
  779         };
  780 #endif
  781 
  782         sense = &xs->sense.scsi_sense;
  783 #ifdef SCSIPI_DEBUG
  784         if (periph->periph_flags & SCSIPI_DB1) {
  785                 int count;
  786                 scsipi_printaddr(periph);
  787                 printf(" sense debug information:\n");
  788                 printf("\tcode 0x%x valid %d\n",
  789                         SSD_RCODE(sense->response_code),
  790                         sense->response_code & SSD_RCODE_VALID ? 1 : 0);
  791                 printf("\tseg 0x%x key 0x%x ili 0x%x eom 0x%x fmark 0x%x\n",
  792                         sense->segment,
  793                         SSD_SENSE_KEY(sense->flags),
  794                         sense->flags & SSD_ILI ? 1 : 0,
  795                         sense->flags & SSD_EOM ? 1 : 0,
  796                         sense->flags & SSD_FILEMARK ? 1 : 0);
  797                 printf("\ninfo: 0x%x 0x%x 0x%x 0x%x followed by %d "
  798                         "extra bytes\n",
  799                         sense->info[0],
  800                         sense->info[1],
  801                         sense->info[2],
  802                         sense->info[3],
  803                         sense->extra_len);
  804                 printf("\textra: ");
  805                 for (count = 0; count < SSD_ADD_BYTES_LIM(sense); count++)
  806                         printf("0x%x ", sense->csi[count]);
  807                 printf("\n");
  808         }
  809 #endif
  810 
  811         /*
  812          * If the periph has it's own error handler, call it first.
  813          * If it returns a legit error value, return that, otherwise
  814          * it wants us to continue with normal error processing.
  815          */
  816         if (periph->periph_switch->psw_error != NULL) {
  817                 SC_DEBUG(periph, SCSIPI_DB2,
  818                     ("calling private err_handler()\n"));
  819                 error = (*periph->periph_switch->psw_error)(xs);
  820                 if (error != EJUSTRETURN)
  821                         return (error);
  822         }
  823         /* otherwise use the default */
  824         switch (SSD_RCODE(sense->response_code)) {
  825 
  826                 /*
  827                  * Old SCSI-1 and SASI devices respond with
  828                  * codes other than 70.
  829                  */
  830         case 0x00:              /* no error (command completed OK) */
  831                 return (0);
  832         case 0x04:              /* drive not ready after it was selected */
  833                 if ((periph->periph_flags & PERIPH_REMOVABLE) != 0)
  834                         periph->periph_flags &= ~PERIPH_MEDIA_LOADED;
  835                 if ((xs->xs_control & XS_CTL_IGNORE_NOT_READY) != 0)
  836                         return (0);
  837                 /* XXX - display some sort of error here? */
  838                 return (EIO);
  839         case 0x20:              /* invalid command */
  840                 if ((xs->xs_control &
  841                      XS_CTL_IGNORE_ILLEGAL_REQUEST) != 0)
  842                         return (0);
  843                 return (EINVAL);
  844         case 0x25:              /* invalid LUN (Adaptec ACB-4000) */
  845                 return (EACCES);
  846 
  847                 /*
  848                  * If it's code 70, use the extended stuff and
  849                  * interpret the key
  850                  */
  851         case 0x71:              /* delayed error */
  852                 scsipi_printaddr(periph);
  853                 key = SSD_SENSE_KEY(sense->flags);
  854                 printf(" DEFERRED ERROR, key = 0x%x\n", key);
  855                 /* FALLTHROUGH */
  856         case 0x70:
  857 #ifndef SCSIVERBOSE
  858                 if ((sense->response_code & SSD_RCODE_VALID) != 0)
  859                         info = _4btol(sense->info);
  860                 else
  861                         info = 0;
  862 #endif
  863                 key = SSD_SENSE_KEY(sense->flags);
  864 
  865                 switch (key) {
  866                 case SKEY_NO_SENSE:
  867                 case SKEY_RECOVERED_ERROR:
  868                         if (xs->resid == xs->datalen && xs->datalen) {
  869                                 /*
  870                                  * Why is this here?
  871                                  */
  872                                 xs->resid = 0;  /* not short read */
  873                         }
  874                 case SKEY_EQUAL:
  875                         error = 0;
  876                         break;
  877                 case SKEY_NOT_READY:
  878                         if ((periph->periph_flags & PERIPH_REMOVABLE) != 0)
  879                                 periph->periph_flags &= ~PERIPH_MEDIA_LOADED;
  880                         if ((xs->xs_control & XS_CTL_IGNORE_NOT_READY) != 0)
  881                                 return (0);
  882                         if (sense->asc == 0x3A) {
  883                                 error = ENODEV; /* Medium not present */
  884                                 if (xs->xs_control & XS_CTL_SILENT_NODEV)
  885                                         return (error);
  886                         } else
  887                                 error = EIO;
  888                         if ((xs->xs_control & XS_CTL_SILENT) != 0)
  889                                 return (error);
  890                         break;
  891                 case SKEY_ILLEGAL_REQUEST:
  892                         if ((xs->xs_control &
  893                              XS_CTL_IGNORE_ILLEGAL_REQUEST) != 0)
  894                                 return (0);
  895                         /*
  896                          * Handle the case where a device reports
  897                          * Logical Unit Not Supported during discovery.
  898                          */
  899                         if ((xs->xs_control & XS_CTL_DISCOVERY) != 0 &&
  900                             sense->asc == 0x25 &&
  901                             sense->ascq == 0x00)
  902                                 return (EINVAL);
  903                         if ((xs->xs_control & XS_CTL_SILENT) != 0)
  904                                 return (EIO);
  905                         error = EINVAL;
  906                         break;
  907                 case SKEY_UNIT_ATTENTION:
  908                         if (sense->asc == 0x29 &&
  909                             sense->ascq == 0x00) {
  910                                 /* device or bus reset */
  911                                 return (ERESTART);
  912                         }
  913                         if ((periph->periph_flags & PERIPH_REMOVABLE) != 0)
  914                                 periph->periph_flags &= ~PERIPH_MEDIA_LOADED;
  915                         if ((xs->xs_control &
  916                              XS_CTL_IGNORE_MEDIA_CHANGE) != 0 ||
  917                                 /* XXX Should reupload any transient state. */
  918                                 (periph->periph_flags &
  919                                  PERIPH_REMOVABLE) == 0) {
  920                                 return (ERESTART);
  921                         }
  922                         if ((xs->xs_control & XS_CTL_SILENT) != 0)
  923                                 return (EIO);
  924                         error = EIO;
  925                         break;
  926                 case SKEY_DATA_PROTECT:
  927                         error = EROFS;
  928                         break;
  929                 case SKEY_BLANK_CHECK:
  930                         error = 0;
  931                         break;
  932                 case SKEY_ABORTED_COMMAND:
  933                         if (xs->xs_retries != 0) {
  934                                 xs->xs_retries--;
  935                                 error = ERESTART;
  936                         } else
  937                                 error = EIO;
  938                         break;
  939                 case SKEY_VOLUME_OVERFLOW:
  940                         error = ENOSPC;
  941                         break;
  942                 default:
  943                         error = EIO;
  944                         break;
  945                 }
  946 
  947 #ifdef SCSIVERBOSE
  948                 if (key && (xs->xs_control & XS_CTL_SILENT) == 0)
  949                         scsipi_print_sense(xs, 0);
  950 #else
  951                 if (key) {
  952                         scsipi_printaddr(periph);
  953                         printf("%s", error_mes[key - 1]);
  954                         if ((sense->response_code & SSD_RCODE_VALID) != 0) {
  955                                 switch (key) {
  956                                 case SKEY_NOT_READY:
  957                                 case SKEY_ILLEGAL_REQUEST:
  958                                 case SKEY_UNIT_ATTENTION:
  959                                 case SKEY_DATA_PROTECT:
  960                                         break;
  961                                 case SKEY_BLANK_CHECK:
  962                                         printf(", requested size: %d (decimal)",
  963                                             info);
  964                                         break;
  965                                 case SKEY_ABORTED_COMMAND:
  966                                         if (xs->xs_retries)
  967                                                 printf(", retrying");
  968                                         printf(", cmd 0x%x, info 0x%x",
  969                                             xs->cmd->opcode, info);
  970                                         break;
  971                                 default:
  972                                         printf(", info = %d (decimal)", info);
  973                                 }
  974                         }
  975                         if (sense->extra_len != 0) {
  976                                 int n;
  977                                 printf(", data =");
  978                                 for (n = 0; n < sense->extra_len; n++)
  979                                         printf(" %02x",
  980                                             sense->csi[n]);
  981                         }
  982                         printf("\n");
  983                 }
  984 #endif
  985                 return (error);
  986 
  987         /*
  988          * Some other code, just report it
  989          */
  990         default:
  991 #if    defined(SCSIDEBUG) || defined(DEBUG)
  992         {
  993                 static const char *uc = "undecodable sense error";
  994                 int i;
  995                 u_int8_t *cptr = (u_int8_t *) sense;
  996                 scsipi_printaddr(periph);
  997                 if (xs->cmd == &xs->cmdstore) {
  998                         printf("%s for opcode 0x%x, data=",
  999                             uc, xs->cmdstore.opcode);
 1000                 } else {
 1001                         printf("%s, data=", uc);
 1002                 }
 1003                 for (i = 0; i < sizeof (sense); i++)
 1004                         printf(" 0x%02x", *(cptr++) & 0xff);
 1005                 printf("\n");
 1006         }
 1007 #else
 1008                 scsipi_printaddr(periph);
 1009                 printf("Sense Error Code 0x%x",
 1010                         SSD_RCODE(sense->response_code));
 1011                 if ((sense->response_code & SSD_RCODE_VALID) != 0) {
 1012                         struct scsi_sense_data_unextended *usense =
 1013                             (struct scsi_sense_data_unextended *)sense;
 1014                         printf(" at block no. %d (decimal)",
 1015                             _3btol(usense->block));
 1016                 }
 1017                 printf("\n");
 1018 #endif
 1019                 return (EIO);
 1020         }
 1021 }
 1022 
 1023 /*
 1024  * scsipi_test_unit_ready:
 1025  *
 1026  *      Issue a `test unit ready' request.
 1027  */
 1028 int
 1029 scsipi_test_unit_ready(struct scsipi_periph *periph, int flags)
 1030 {
 1031         struct scsi_test_unit_ready cmd;
 1032         int retries;
 1033 
 1034         /* some ATAPI drives don't support TEST UNIT READY. Sigh */
 1035         if (periph->periph_quirks & PQUIRK_NOTUR)
 1036                 return (0);
 1037 
 1038         if (flags & XS_CTL_DISCOVERY)
 1039                 retries = 0;
 1040         else
 1041                 retries = SCSIPIRETRIES;
 1042 
 1043         memset(&cmd, 0, sizeof(cmd));
 1044         cmd.opcode = SCSI_TEST_UNIT_READY;
 1045 
 1046         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd), 0, 0,
 1047             retries, 10000, NULL, flags));
 1048 }
 1049 
 1050 /*
 1051  * scsipi_inquire:
 1052  *
 1053  *      Ask the device about itself.
 1054  */
 1055 int
 1056 scsipi_inquire(struct scsipi_periph *periph, struct scsipi_inquiry_data *inqbuf,
 1057     int flags)
 1058 {
 1059         struct scsipi_inquiry cmd;
 1060         int error;
 1061         int retries;
 1062 
 1063         if (flags & XS_CTL_DISCOVERY)
 1064                 retries = 0;
 1065         else
 1066                 retries = SCSIPIRETRIES;
 1067 
 1068         /*
 1069          * If we request more data than the device can provide, it SHOULD just
 1070          * return a short reponse.  However, some devices error with an
 1071          * ILLEGAL REQUEST sense code, and yet others have even more special
 1072          * failture modes (such as the GL641USB flash adapter, which goes loony
 1073          * and sends corrupted CRCs).  To work around this, and to bring our
 1074          * behavior more in line with other OSes, we do a shorter inquiry,
 1075          * covering all the SCSI-2 information, first, and then request more
 1076          * data iff the "additional length" field indicates there is more.
 1077          * - mycroft, 2003/10/16
 1078          */
 1079         memset(&cmd, 0, sizeof(cmd));
 1080         cmd.opcode = INQUIRY;
 1081         cmd.length = SCSIPI_INQUIRY_LENGTH_SCSI2;
 1082         error = scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1083             (void *)inqbuf, SCSIPI_INQUIRY_LENGTH_SCSI2, retries,
 1084             10000, NULL, flags | XS_CTL_DATA_IN);
 1085         if (!error &&
 1086             inqbuf->additional_length > SCSIPI_INQUIRY_LENGTH_SCSI2 - 4) {
 1087 #if 0
 1088 printf("inquire: addlen=%d, retrying\n", inqbuf->additional_length);
 1089 #endif
 1090                 cmd.length = SCSIPI_INQUIRY_LENGTH_SCSI3;
 1091                 error = scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1092                     (void *)inqbuf, SCSIPI_INQUIRY_LENGTH_SCSI3, retries,
 1093                     10000, NULL, flags | XS_CTL_DATA_IN);
 1094 #if 0
 1095 printf("inquire: error=%d\n", error);
 1096 #endif
 1097         }
 1098 
 1099 #ifdef SCSI_OLD_NOINQUIRY
 1100         /*
 1101          * Kludge for the Adaptec ACB-4000 SCSI->MFM translator.
 1102          * This board doesn't support the INQUIRY command at all.
 1103          */
 1104         if (error == EINVAL || error == EACCES) {
 1105                 /*
 1106                  * Conjure up an INQUIRY response.
 1107                  */
 1108                 inqbuf->device = (error == EINVAL ?
 1109                          SID_QUAL_LU_PRESENT :
 1110                          SID_QUAL_LU_NOTPRESENT) | T_DIRECT;
 1111                 inqbuf->dev_qual2 = 0;
 1112                 inqbuf->version = 0;
 1113                 inqbuf->response_format = SID_FORMAT_SCSI1;
 1114                 inqbuf->additional_length = SCSIPI_INQUIRY_LENGTH_SCSI2 - 4;
 1115                 inqbuf->flags1 = inqbuf->flags2 = inqbuf->flags3 = 0;
 1116                 memcpy(inqbuf->vendor, "ADAPTEC ACB-4000            ", 28);
 1117                 error = 0;
 1118         }
 1119 
 1120         /*
 1121          * Kludge for the Emulex MT-02 SCSI->QIC translator.
 1122          * This board gives an empty response to an INQUIRY command.
 1123          */
 1124         else if (error == 0 &&
 1125             inqbuf->device == (SID_QUAL_LU_PRESENT | T_DIRECT) &&
 1126             inqbuf->dev_qual2 == 0 &&
 1127             inqbuf->version == 0 &&
 1128             inqbuf->response_format == SID_FORMAT_SCSI1) {
 1129                 /*
 1130                  * Fill out the INQUIRY response.
 1131                  */
 1132                 inqbuf->device = (SID_QUAL_LU_PRESENT | T_SEQUENTIAL);
 1133                 inqbuf->dev_qual2 = SID_REMOVABLE;
 1134                 inqbuf->additional_length = SCSIPI_INQUIRY_LENGTH_SCSI2 - 4;
 1135                 inqbuf->flags1 = inqbuf->flags2 = inqbuf->flags3 = 0;
 1136                 memcpy(inqbuf->vendor, "EMULEX  MT-02 QIC           ", 28);
 1137         }
 1138 #endif /* SCSI_OLD_NOINQUIRY */
 1139 
 1140         return error;
 1141 }
 1142 
 1143 /*
 1144  * scsipi_prevent:
 1145  *
 1146  *      Prevent or allow the user to remove the media
 1147  */
 1148 int
 1149 scsipi_prevent(struct scsipi_periph *periph, int type, int flags)
 1150 {
 1151         struct scsi_prevent_allow_medium_removal cmd;
 1152 
 1153         if (periph->periph_quirks & PQUIRK_NODOORLOCK)
 1154                 return 0;
 1155 
 1156         memset(&cmd, 0, sizeof(cmd));
 1157         cmd.opcode = SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL;
 1158         cmd.how = type;
 1159 
 1160         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd), 0, 0,
 1161             SCSIPIRETRIES, 5000, NULL, flags));
 1162 }
 1163 
 1164 /*
 1165  * scsipi_start:
 1166  *
 1167  *      Send a START UNIT.
 1168  */
 1169 int
 1170 scsipi_start(struct scsipi_periph *periph, int type, int flags)
 1171 {
 1172         struct scsipi_start_stop cmd;
 1173 
 1174         memset(&cmd, 0, sizeof(cmd));
 1175         cmd.opcode = START_STOP;
 1176         cmd.byte2 = 0x00;
 1177         cmd.how = type;
 1178 
 1179         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd), 0, 0,
 1180             SCSIPIRETRIES, (type & SSS_START) ? 60000 : 10000, NULL, flags));
 1181 }
 1182 
 1183 /*
 1184  * scsipi_mode_sense, scsipi_mode_sense_big:
 1185  *      get a sense page from a device
 1186  */
 1187 
 1188 int
 1189 scsipi_mode_sense(struct scsipi_periph *periph, int byte2, int page,
 1190     struct scsi_mode_parameter_header_6 *data, int len, int flags, int retries,
 1191     int timeout)
 1192 {
 1193         struct scsi_mode_sense_6 cmd;
 1194 
 1195         memset(&cmd, 0, sizeof(cmd));
 1196         cmd.opcode = SCSI_MODE_SENSE_6;
 1197         cmd.byte2 = byte2;
 1198         cmd.page = page;
 1199         cmd.length = len & 0xff;
 1200 
 1201         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1202             (void *)data, len, retries, timeout, NULL, flags | XS_CTL_DATA_IN));
 1203 }
 1204 
 1205 int
 1206 scsipi_mode_sense_big(struct scsipi_periph *periph, int byte2, int page,
 1207     struct scsi_mode_parameter_header_10 *data, int len, int flags, int retries,
 1208     int timeout)
 1209 {
 1210         struct scsi_mode_sense_10 cmd;
 1211 
 1212         memset(&cmd, 0, sizeof(cmd));
 1213         cmd.opcode = SCSI_MODE_SENSE_10;
 1214         cmd.byte2 = byte2;
 1215         cmd.page = page;
 1216         _lto2b(len, cmd.length);
 1217 
 1218         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1219             (void *)data, len, retries, timeout, NULL, flags | XS_CTL_DATA_IN));
 1220 }
 1221 
 1222 int
 1223 scsipi_mode_select(struct scsipi_periph *periph, int byte2,
 1224     struct scsi_mode_parameter_header_6 *data, int len, int flags, int retries,
 1225     int timeout)
 1226 {
 1227         struct scsi_mode_select_6 cmd;
 1228 
 1229         memset(&cmd, 0, sizeof(cmd));
 1230         cmd.opcode = SCSI_MODE_SELECT_6;
 1231         cmd.byte2 = byte2;
 1232         cmd.length = len & 0xff;
 1233 
 1234         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1235             (void *)data, len, retries, timeout, NULL, flags | XS_CTL_DATA_OUT));
 1236 }
 1237 
 1238 int
 1239 scsipi_mode_select_big(struct scsipi_periph *periph, int byte2,
 1240     struct scsi_mode_parameter_header_10 *data, int len, int flags, int retries,
 1241     int timeout)
 1242 {
 1243         struct scsi_mode_select_10 cmd;
 1244 
 1245         memset(&cmd, 0, sizeof(cmd));
 1246         cmd.opcode = SCSI_MODE_SELECT_10;
 1247         cmd.byte2 = byte2;
 1248         _lto2b(len, cmd.length);
 1249 
 1250         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1251             (void *)data, len, retries, timeout, NULL, flags | XS_CTL_DATA_OUT));
 1252 }
 1253 
 1254 /*
 1255  * scsipi_done:
 1256  *
 1257  *      This routine is called by an adapter's interrupt handler when
 1258  *      an xfer is completed.
 1259  */
 1260 void
 1261 scsipi_done(struct scsipi_xfer *xs)
 1262 {
 1263         struct scsipi_periph *periph = xs->xs_periph;
 1264         struct scsipi_channel *chan = periph->periph_channel;
 1265         int s, freezecnt;
 1266 
 1267         SC_DEBUG(periph, SCSIPI_DB2, ("scsipi_done\n"));
 1268 #ifdef SCSIPI_DEBUG
 1269         if (periph->periph_dbflags & SCSIPI_DB1)
 1270                 show_scsipi_cmd(xs);
 1271 #endif
 1272 
 1273         s = splbio();
 1274         /*
 1275          * The resource this command was using is now free.
 1276          */
 1277         if (xs->xs_status & XS_STS_DONE) {
 1278                 /* XXX in certain circumstances, such as a device
 1279                  * being detached, a xs that has already been
 1280                  * scsipi_done()'d by the main thread will be done'd
 1281                  * again by scsibusdetach(). Putting the xs on the
 1282                  * chan_complete queue causes list corruption and
 1283                  * everyone dies. This prevents that, but perhaps
 1284                  * there should be better coordination somewhere such
 1285                  * that this won't ever happen (and can be turned into
 1286                  * a KASSERT().
 1287                  */
 1288                 splx(s);
 1289                 goto out;
 1290         }
 1291         scsipi_put_resource(chan);
 1292         xs->xs_periph->periph_sent--;
 1293 
 1294         /*
 1295          * If the command was tagged, free the tag.
 1296          */
 1297         if (XS_CTL_TAGTYPE(xs) != 0)
 1298                 scsipi_put_tag(xs);
 1299         else
 1300                 periph->periph_flags &= ~PERIPH_UNTAG;
 1301 
 1302         /* Mark the command as `done'. */
 1303         xs->xs_status |= XS_STS_DONE;
 1304 
 1305 #ifdef DIAGNOSTIC
 1306         if ((xs->xs_control & (XS_CTL_ASYNC|XS_CTL_POLL)) ==
 1307             (XS_CTL_ASYNC|XS_CTL_POLL))
 1308                 panic("scsipi_done: ASYNC and POLL");
 1309 #endif
 1310 
 1311         /*
 1312          * If the xfer had an error of any sort, freeze the
 1313          * periph's queue.  Freeze it again if we were requested
 1314          * to do so in the xfer.
 1315          */
 1316         freezecnt = 0;
 1317         if (xs->error != XS_NOERROR)
 1318                 freezecnt++;
 1319         if (xs->xs_control & XS_CTL_FREEZE_PERIPH)
 1320                 freezecnt++;
 1321         if (freezecnt != 0)
 1322                 scsipi_periph_freeze(periph, freezecnt);
 1323 
 1324         /*
 1325          * record the xfer with a pending sense, in case a SCSI reset is
 1326          * received before the thread is waked up.
 1327          */
 1328         if (xs->error == XS_BUSY && xs->status == SCSI_CHECK) {
 1329                 periph->periph_flags |= PERIPH_SENSE;
 1330                 periph->periph_xscheck = xs;
 1331         }
 1332 
 1333         /*
 1334          * If this was an xfer that was not to complete asynchronously,
 1335          * let the requesting thread perform error checking/handling
 1336          * in its context.
 1337          */
 1338         if ((xs->xs_control & XS_CTL_ASYNC) == 0) {
 1339                 splx(s);
 1340                 /*
 1341                  * If it's a polling job, just return, to unwind the
 1342                  * call graph.  We don't need to restart the queue,
 1343                  * because pollings jobs are treated specially, and
 1344                  * are really only used during crash dumps anyway
 1345                  * (XXX or during boot-time autconfiguration of
 1346                  * ATAPI devices).
 1347                  */
 1348                 if (xs->xs_control & XS_CTL_POLL)
 1349                         return;
 1350                 wakeup(xs);
 1351                 goto out;
 1352         }
 1353 
 1354         /*
 1355          * Catch the extremely common case of I/O completing
 1356          * without error; no use in taking a context switch
 1357          * if we can handle it in interrupt context.
 1358          */
 1359         if (xs->error == XS_NOERROR) {
 1360                 splx(s);
 1361                 (void) scsipi_complete(xs);
 1362                 goto out;
 1363         }
 1364 
 1365         /*
 1366          * There is an error on this xfer.  Put it on the channel's
 1367          * completion queue, and wake up the completion thread.
 1368          */
 1369         TAILQ_INSERT_TAIL(&chan->chan_complete, xs, channel_q);
 1370         splx(s);
 1371         wakeup(&chan->chan_complete);
 1372 
 1373  out:
 1374         /*
 1375          * If there are more xfers on the channel's queue, attempt to
 1376          * run them.
 1377          */
 1378         scsipi_run_queue(chan);
 1379 }
 1380 
 1381 /*
 1382  * scsipi_complete:
 1383  *
 1384  *      Completion of a scsipi_xfer.  This is the guts of scsipi_done().
 1385  *
 1386  *      NOTE: This routine MUST be called with valid thread context
 1387  *      except for the case where the following two conditions are
 1388  *      true:
 1389  *
 1390  *              xs->error == XS_NOERROR
 1391  *              XS_CTL_ASYNC is set in xs->xs_control
 1392  *
 1393  *      The semantics of this routine can be tricky, so here is an
 1394  *      explanation:
 1395  *
 1396  *              0               Xfer completed successfully.
 1397  *
 1398  *              ERESTART        Xfer had an error, but was restarted.
 1399  *
 1400  *              anything else   Xfer had an error, return value is Unix
 1401  *                              errno.
 1402  *
 1403  *      If the return value is anything but ERESTART:
 1404  *
 1405  *              - If XS_CTL_ASYNC is set, `xs' has been freed back to
 1406  *                the pool.
 1407  *              - If there is a buf associated with the xfer,
 1408  *                it has been biodone()'d.
 1409  */
 1410 static int
 1411 scsipi_complete(struct scsipi_xfer *xs)
 1412 {
 1413         struct scsipi_periph *periph = xs->xs_periph;
 1414         struct scsipi_channel *chan = periph->periph_channel;
 1415         int error, s;
 1416 
 1417 #ifdef DIAGNOSTIC
 1418         if ((xs->xs_control & XS_CTL_ASYNC) != 0 && xs->bp == NULL)
 1419                 panic("scsipi_complete: XS_CTL_ASYNC but no buf");
 1420 #endif
 1421         /*
 1422          * If command terminated with a CHECK CONDITION, we need to issue a
 1423          * REQUEST_SENSE command. Once the REQUEST_SENSE has been processed
 1424          * we'll have the real status.
 1425          * Must be processed at splbio() to avoid missing a SCSI bus reset
 1426          * for this command.
 1427          */
 1428         s = splbio();
 1429         if (xs->error == XS_BUSY && xs->status == SCSI_CHECK) {
 1430                 /* request sense for a request sense ? */
 1431                 if (xs->xs_control & XS_CTL_REQSENSE) {
 1432                         scsipi_printaddr(periph);
 1433                         printf("request sense for a request sense ?\n");
 1434                         /* XXX maybe we should reset the device ? */
 1435                         /* we've been frozen because xs->error != XS_NOERROR */
 1436                         scsipi_periph_thaw(periph, 1);
 1437                         splx(s);
 1438                         if (xs->resid < xs->datalen) {
 1439                                 printf("we read %d bytes of sense anyway:\n",
 1440                                     xs->datalen - xs->resid);
 1441 #ifdef SCSIVERBOSE
 1442                                 scsipi_print_sense_data((void *)xs->data, 0);
 1443 #endif
 1444                         }
 1445                         return EINVAL;
 1446                 }
 1447                 scsipi_request_sense(xs);
 1448         }
 1449         splx(s);
 1450 
 1451         /*
 1452          * If it's a user level request, bypass all usual completion
 1453          * processing, let the user work it out..
 1454          */
 1455         if ((xs->xs_control & XS_CTL_USERCMD) != 0) {
 1456                 SC_DEBUG(periph, SCSIPI_DB3, ("calling user done()\n"));
 1457                 if (xs->error != XS_NOERROR)
 1458                         scsipi_periph_thaw(periph, 1);
 1459                 scsipi_user_done(xs);
 1460                 SC_DEBUG(periph, SCSIPI_DB3, ("returned from user done()\n "));
 1461                 return 0;
 1462         }
 1463 
 1464         switch (xs->error) {
 1465         case XS_NOERROR:
 1466                 error = 0;
 1467                 break;
 1468 
 1469         case XS_SENSE:
 1470         case XS_SHORTSENSE:
 1471                 error = (*chan->chan_bustype->bustype_interpret_sense)(xs);
 1472                 break;
 1473 
 1474         case XS_RESOURCE_SHORTAGE:
 1475                 /*
 1476                  * XXX Should freeze channel's queue.
 1477                  */
 1478                 scsipi_printaddr(periph);
 1479                 printf("adapter resource shortage\n");
 1480                 /* FALLTHROUGH */
 1481 
 1482         case XS_BUSY:
 1483                 if (xs->error == XS_BUSY && xs->status == SCSI_QUEUE_FULL) {
 1484                         struct scsipi_max_openings mo;
 1485 
 1486                         /*
 1487                          * We set the openings to active - 1, assuming that
 1488                          * the command that got us here is the first one that
 1489                          * can't fit into the device's queue.  If that's not
 1490                          * the case, I guess we'll find out soon enough.
 1491                          */
 1492                         mo.mo_target = periph->periph_target;
 1493                         mo.mo_lun = periph->periph_lun;
 1494                         if (periph->periph_active < periph->periph_openings)
 1495                                 mo.mo_openings = periph->periph_active - 1;
 1496                         else
 1497                                 mo.mo_openings = periph->periph_openings - 1;
 1498 #ifdef DIAGNOSTIC
 1499                         if (mo.mo_openings < 0) {
 1500                                 scsipi_printaddr(periph);
 1501                                 printf("QUEUE FULL resulted in < 0 openings\n");
 1502                                 panic("scsipi_done");
 1503                         }
 1504 #endif
 1505                         if (mo.mo_openings == 0) {
 1506                                 scsipi_printaddr(periph);
 1507                                 printf("QUEUE FULL resulted in 0 openings\n");
 1508                                 mo.mo_openings = 1;
 1509                         }
 1510                         scsipi_async_event(chan, ASYNC_EVENT_MAX_OPENINGS, &mo);
 1511                         error = ERESTART;
 1512                 } else if (xs->xs_retries != 0) {
 1513                         xs->xs_retries--;
 1514                         /*
 1515                          * Wait one second, and try again.
 1516                          */
 1517                         if ((xs->xs_control & XS_CTL_POLL) ||
 1518                             (chan->chan_flags & SCSIPI_CHAN_TACTIVE) == 0) {
 1519                                 delay(1000000);
 1520                         } else if (!callout_pending(&periph->periph_callout)) {
 1521                                 scsipi_periph_freeze(periph, 1);
 1522                                 callout_reset(&periph->periph_callout,
 1523                                     hz, scsipi_periph_timed_thaw, periph);
 1524                         }
 1525                         error = ERESTART;
 1526                 } else
 1527                         error = EBUSY;
 1528                 break;
 1529 
 1530         case XS_REQUEUE:
 1531                 error = ERESTART;
 1532                 break;
 1533 
 1534         case XS_SELTIMEOUT:
 1535         case XS_TIMEOUT:
 1536                 /*
 1537                  * If the device hasn't gone away, honor retry counts.
 1538                  *
 1539                  * Note that if we're in the middle of probing it,
 1540                  * it won't be found because it isn't here yet so
 1541                  * we won't honor the retry count in that case.
 1542                  */
 1543                 if (scsipi_lookup_periph(chan, periph->periph_target,
 1544                     periph->periph_lun) && xs->xs_retries != 0) {
 1545                         xs->xs_retries--;
 1546                         error = ERESTART;
 1547                 } else
 1548                         error = EIO;
 1549                 break;
 1550 
 1551         case XS_RESET:
 1552                 if (xs->xs_control & XS_CTL_REQSENSE) {
 1553                         /*
 1554                          * request sense interrupted by reset: signal it
 1555                          * with EINTR return code.
 1556                          */
 1557                         error = EINTR;
 1558                 } else {
 1559                         if (xs->xs_retries != 0) {
 1560                                 xs->xs_retries--;
 1561                                 error = ERESTART;
 1562                         } else
 1563                                 error = EIO;
 1564                 }
 1565                 break;
 1566 
 1567         case XS_DRIVER_STUFFUP:
 1568                 scsipi_printaddr(periph);
 1569                 printf("generic HBA error\n");
 1570                 error = EIO;
 1571                 break;
 1572         default:
 1573                 scsipi_printaddr(periph);
 1574                 printf("invalid return code from adapter: %d\n", xs->error);
 1575                 error = EIO;
 1576                 break;
 1577         }
 1578 
 1579         s = splbio();
 1580         if (error == ERESTART) {
 1581                 /*
 1582                  * If we get here, the periph has been thawed and frozen
 1583                  * again if we had to issue recovery commands.  Alternatively,
 1584                  * it may have been frozen again and in a timed thaw.  In
 1585                  * any case, we thaw the periph once we re-enqueue the
 1586                  * command.  Once the periph is fully thawed, it will begin
 1587                  * operation again.
 1588                  */
 1589                 xs->error = XS_NOERROR;
 1590                 xs->status = SCSI_OK;
 1591                 xs->xs_status &= ~XS_STS_DONE;
 1592                 xs->xs_requeuecnt++;
 1593                 error = scsipi_enqueue(xs);
 1594                 if (error == 0) {
 1595                         scsipi_periph_thaw(periph, 1);
 1596                         splx(s);
 1597                         return (ERESTART);
 1598                 }
 1599         }
 1600 
 1601         /*
 1602          * scsipi_done() freezes the queue if not XS_NOERROR.
 1603          * Thaw it here.
 1604          */
 1605         if (xs->error != XS_NOERROR)
 1606                 scsipi_periph_thaw(periph, 1);
 1607 
 1608         if (periph->periph_switch->psw_done)
 1609                 periph->periph_switch->psw_done(xs, error);
 1610 
 1611         if (xs->xs_control & XS_CTL_ASYNC)
 1612                 scsipi_put_xs(xs);
 1613         splx(s);
 1614 
 1615         return (error);
 1616 }
 1617 
 1618 /*
 1619  * Issue a request sense for the given scsipi_xfer. Called when the xfer
 1620  * returns with a CHECK_CONDITION status. Must be called in valid thread
 1621  * context and at splbio().
 1622  */
 1623 
 1624 static void
 1625 scsipi_request_sense(struct scsipi_xfer *xs)
 1626 {
 1627         struct scsipi_periph *periph = xs->xs_periph;
 1628         int flags, error;
 1629         struct scsi_request_sense cmd;
 1630 
 1631         periph->periph_flags |= PERIPH_SENSE;
 1632 
 1633         /* if command was polling, request sense will too */
 1634         flags = xs->xs_control & XS_CTL_POLL;
 1635         /* Polling commands can't sleep */
 1636         if (flags)
 1637                 flags |= XS_CTL_NOSLEEP;
 1638 
 1639         flags |= XS_CTL_REQSENSE | XS_CTL_URGENT | XS_CTL_DATA_IN |
 1640             XS_CTL_THAW_PERIPH | XS_CTL_FREEZE_PERIPH;
 1641 
 1642         memset(&cmd, 0, sizeof(cmd));
 1643         cmd.opcode = SCSI_REQUEST_SENSE;
 1644         cmd.length = sizeof(struct scsi_sense_data);
 1645 
 1646         error = scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1647             (void *)&xs->sense.scsi_sense, sizeof(struct scsi_sense_data),
 1648             0, 1000, NULL, flags);
 1649         periph->periph_flags &= ~PERIPH_SENSE;
 1650         periph->periph_xscheck = NULL;
 1651         switch (error) {
 1652         case 0:
 1653                 /* we have a valid sense */
 1654                 xs->error = XS_SENSE;
 1655                 return;
 1656         case EINTR:
 1657                 /* REQUEST_SENSE interrupted by bus reset. */
 1658                 xs->error = XS_RESET;
 1659                 return;
 1660         case EIO:
 1661                  /* request sense coudn't be performed */
 1662                 /*
 1663                  * XXX this isn't quite right but we don't have anything
 1664                  * better for now
 1665                  */
 1666                 xs->error = XS_DRIVER_STUFFUP;
 1667                 return;
 1668         default:
 1669                  /* Notify that request sense failed. */
 1670                 xs->error = XS_DRIVER_STUFFUP;
 1671                 scsipi_printaddr(periph);
 1672                 printf("request sense failed with error %d\n", error);
 1673                 return;
 1674         }
 1675 }
 1676 
 1677 /*
 1678  * scsipi_enqueue:
 1679  *
 1680  *      Enqueue an xfer on a channel.
 1681  */
 1682 static int
 1683 scsipi_enqueue(struct scsipi_xfer *xs)
 1684 {
 1685         struct scsipi_channel *chan = xs->xs_periph->periph_channel;
 1686         struct scsipi_xfer *qxs;
 1687         int s;
 1688 
 1689         s = splbio();
 1690 
 1691         /*
 1692          * If the xfer is to be polled, and there are already jobs on
 1693          * the queue, we can't proceed.
 1694          */
 1695         if ((xs->xs_control & XS_CTL_POLL) != 0 &&
 1696             TAILQ_FIRST(&chan->chan_queue) != NULL) {
 1697                 splx(s);
 1698                 xs->error = XS_DRIVER_STUFFUP;
 1699                 return (EAGAIN);
 1700         }
 1701 
 1702         /*
 1703          * If we have an URGENT xfer, it's an error recovery command
 1704          * and it should just go on the head of the channel's queue.
 1705          */
 1706         if (xs->xs_control & XS_CTL_URGENT) {
 1707                 TAILQ_INSERT_HEAD(&chan->chan_queue, xs, channel_q);
 1708                 goto out;
 1709         }
 1710 
 1711         /*
 1712          * If this xfer has already been on the queue before, we
 1713          * need to reinsert it in the correct order.  That order is:
 1714          *
 1715          *      Immediately before the first xfer for this periph
 1716          *      with a requeuecnt less than xs->xs_requeuecnt.
 1717          *
 1718          * Failing that, at the end of the queue.  (We'll end up
 1719          * there naturally.)
 1720          */
 1721         if (xs->xs_requeuecnt != 0) {
 1722                 for (qxs = TAILQ_FIRST(&chan->chan_queue); qxs != NULL;
 1723                      qxs = TAILQ_NEXT(qxs, channel_q)) {
 1724                         if (qxs->xs_periph == xs->xs_periph &&
 1725                             qxs->xs_requeuecnt < xs->xs_requeuecnt)
 1726                                 break;
 1727                 }
 1728                 if (qxs != NULL) {
 1729                         TAILQ_INSERT_AFTER(&chan->chan_queue, qxs, xs,
 1730                             channel_q);
 1731                         goto out;
 1732                 }
 1733         }
 1734         TAILQ_INSERT_TAIL(&chan->chan_queue, xs, channel_q);
 1735  out:
 1736         if (xs->xs_control & XS_CTL_THAW_PERIPH)
 1737                 scsipi_periph_thaw(xs->xs_periph, 1);
 1738         splx(s);
 1739         return (0);
 1740 }
 1741 
 1742 /*
 1743  * scsipi_run_queue:
 1744  *
 1745  *      Start as many xfers as possible running on the channel.
 1746  */
 1747 static void
 1748 scsipi_run_queue(struct scsipi_channel *chan)
 1749 {
 1750         struct scsipi_xfer *xs;
 1751         struct scsipi_periph *periph;
 1752         int s;
 1753 
 1754         for (;;) {
 1755                 s = splbio();
 1756 
 1757                 /*
 1758                  * If the channel is frozen, we can't do any work right
 1759                  * now.
 1760                  */
 1761                 if (chan->chan_qfreeze != 0) {
 1762                         splx(s);
 1763                         return;
 1764                 }
 1765 
 1766                 /*
 1767                  * Look for work to do, and make sure we can do it.
 1768                  */
 1769                 for (xs = TAILQ_FIRST(&chan->chan_queue); xs != NULL;
 1770                      xs = TAILQ_NEXT(xs, channel_q)) {
 1771                         periph = xs->xs_periph;
 1772 
 1773                         if ((periph->periph_sent >= periph->periph_openings) ||
 1774                             periph->periph_qfreeze != 0 ||
 1775                             (periph->periph_flags & PERIPH_UNTAG) != 0)
 1776                                 continue;
 1777 
 1778                         if ((periph->periph_flags &
 1779                             (PERIPH_RECOVERING | PERIPH_SENSE)) != 0 &&
 1780                             (xs->xs_control & XS_CTL_URGENT) == 0)
 1781                                 continue;
 1782 
 1783                         /*
 1784                          * We can issue this xfer!
 1785                          */
 1786                         goto got_one;
 1787                 }
 1788 
 1789                 /*
 1790                  * Can't find any work to do right now.
 1791                  */
 1792                 splx(s);
 1793                 return;
 1794 
 1795  got_one:
 1796                 /*
 1797                  * Have an xfer to run.  Allocate a resource from
 1798                  * the adapter to run it.  If we can't allocate that
 1799                  * resource, we don't dequeue the xfer.
 1800                  */
 1801                 if (scsipi_get_resource(chan) == 0) {
 1802                         /*
 1803                          * Adapter is out of resources.  If the adapter
 1804                          * supports it, attempt to grow them.
 1805                          */
 1806                         if (scsipi_grow_resources(chan) == 0) {
 1807                                 /*
 1808                                  * Wasn't able to grow resources,
 1809                                  * nothing more we can do.
 1810                                  */
 1811                                 if (xs->xs_control & XS_CTL_POLL) {
 1812                                         scsipi_printaddr(xs->xs_periph);
 1813                                         printf("polling command but no "
 1814                                             "adapter resources");
 1815                                         /* We'll panic shortly... */
 1816                                 }
 1817                                 splx(s);
 1818 
 1819                                 /*
 1820                                  * XXX: We should be able to note that
 1821                                  * XXX: that resources are needed here!
 1822                                  */
 1823                                 return;
 1824                         }
 1825                         /*
 1826                          * scsipi_grow_resources() allocated the resource
 1827                          * for us.
 1828                          */
 1829                 }
 1830 
 1831                 /*
 1832                  * We have a resource to run this xfer, do it!
 1833                  */
 1834                 TAILQ_REMOVE(&chan->chan_queue, xs, channel_q);
 1835 
 1836                 /*
 1837                  * If the command is to be tagged, allocate a tag ID
 1838                  * for it.
 1839                  */
 1840                 if (XS_CTL_TAGTYPE(xs) != 0)
 1841                         scsipi_get_tag(xs);
 1842                 else
 1843                         periph->periph_flags |= PERIPH_UNTAG;
 1844                 periph->periph_sent++;
 1845                 splx(s);
 1846 
 1847                 scsipi_adapter_request(chan, ADAPTER_REQ_RUN_XFER, xs);
 1848         }
 1849 #ifdef DIAGNOSTIC
 1850         panic("scsipi_run_queue: impossible");
 1851 #endif
 1852 }
 1853 
 1854 /*
 1855  * scsipi_execute_xs:
 1856  *
 1857  *      Begin execution of an xfer, waiting for it to complete, if necessary.
 1858  */
 1859 int
 1860 scsipi_execute_xs(struct scsipi_xfer *xs)
 1861 {
 1862         struct scsipi_periph *periph = xs->xs_periph;
 1863         struct scsipi_channel *chan = periph->periph_channel;
 1864         int oasync, async, poll, error, s;
 1865 
 1866         KASSERT(!cold);
 1867 
 1868         (chan->chan_bustype->bustype_cmd)(xs);
 1869 
 1870         if (xs->xs_control & XS_CTL_DATA_ONSTACK) {
 1871 #if 1
 1872                 if (xs->xs_control & XS_CTL_ASYNC)
 1873                         panic("scsipi_execute_xs: on stack and async");
 1874 #endif
 1875                 /*
 1876                  * If the I/O buffer is allocated on stack, the
 1877                  * process must NOT be swapped out, as the device will
 1878                  * be accessing the stack.
 1879                  */
 1880                 uvm_lwp_hold(curlwp);
 1881         }
 1882 
 1883         xs->xs_status &= ~XS_STS_DONE;
 1884         xs->error = XS_NOERROR;
 1885         xs->resid = xs->datalen;
 1886         xs->status = SCSI_OK;
 1887 
 1888 #ifdef SCSIPI_DEBUG
 1889         if (xs->xs_periph->periph_dbflags & SCSIPI_DB3) {
 1890                 printf("scsipi_execute_xs: ");
 1891                 show_scsipi_xs(xs);
 1892                 printf("\n");
 1893         }
 1894 #endif
 1895 
 1896         /*
 1897          * Deal with command tagging:
 1898          *
 1899          *      - If the device's current operating mode doesn't
 1900          *        include tagged queueing, clear the tag mask.
 1901          *
 1902          *      - If the device's current operating mode *does*
 1903          *        include tagged queueing, set the tag_type in
 1904          *        the xfer to the appropriate byte for the tag
 1905          *        message.
 1906          */
 1907         if ((PERIPH_XFER_MODE(periph) & PERIPH_CAP_TQING) == 0 ||
 1908                 (xs->xs_control & XS_CTL_REQSENSE)) {
 1909                 xs->xs_control &= ~XS_CTL_TAGMASK;
 1910                 xs->xs_tag_type = 0;
 1911         } else {
 1912                 /*
 1913                  * If the request doesn't specify a tag, give Head
 1914                  * tags to URGENT operations and Ordered tags to
 1915                  * everything else.
 1916                  */
 1917                 if (XS_CTL_TAGTYPE(xs) == 0) {
 1918                         if (xs->xs_control & XS_CTL_URGENT)
 1919                                 xs->xs_control |= XS_CTL_HEAD_TAG;
 1920                         else
 1921                                 xs->xs_control |= XS_CTL_ORDERED_TAG;
 1922                 }
 1923 
 1924                 switch (XS_CTL_TAGTYPE(xs)) {
 1925                 case XS_CTL_ORDERED_TAG:
 1926                         xs->xs_tag_type = MSG_ORDERED_Q_TAG;
 1927                         break;
 1928 
 1929                 case XS_CTL_SIMPLE_TAG:
 1930                         xs->xs_tag_type = MSG_SIMPLE_Q_TAG;
 1931                         break;
 1932 
 1933                 case XS_CTL_HEAD_TAG:
 1934                         xs->xs_tag_type = MSG_HEAD_OF_Q_TAG;
 1935                         break;
 1936 
 1937                 default:
 1938                         scsipi_printaddr(periph);
 1939                         printf("invalid tag mask 0x%08x\n",
 1940                             XS_CTL_TAGTYPE(xs));
 1941                         panic("scsipi_execute_xs");
 1942                 }
 1943         }
 1944 
 1945         /* If the adaptor wants us to poll, poll. */
 1946         if (chan->chan_adapter->adapt_flags & SCSIPI_ADAPT_POLL_ONLY)
 1947                 xs->xs_control |= XS_CTL_POLL;
 1948 
 1949         /*
 1950          * If we don't yet have a completion thread, or we are to poll for
 1951          * completion, clear the ASYNC flag.
 1952          */
 1953         oasync =  (xs->xs_control & XS_CTL_ASYNC);
 1954         if (chan->chan_thread == NULL || (xs->xs_control & XS_CTL_POLL) != 0)
 1955                 xs->xs_control &= ~XS_CTL_ASYNC;
 1956 
 1957         async = (xs->xs_control & XS_CTL_ASYNC);
 1958         poll = (xs->xs_control & XS_CTL_POLL);
 1959 
 1960 #ifdef DIAGNOSTIC
 1961         if (oasync != 0 && xs->bp == NULL)
 1962                 panic("scsipi_execute_xs: XS_CTL_ASYNC but no buf");
 1963 #endif
 1964 
 1965         /*
 1966          * Enqueue the transfer.  If we're not polling for completion, this
 1967          * should ALWAYS return `no error'.
 1968          */
 1969         error = scsipi_enqueue(xs);
 1970         if (error) {
 1971                 if (poll == 0) {
 1972                         scsipi_printaddr(periph);
 1973                         printf("not polling, but enqueue failed with %d\n",
 1974                             error);
 1975                         panic("scsipi_execute_xs");
 1976                 }
 1977 
 1978                 scsipi_printaddr(periph);
 1979                 printf("should have flushed queue?\n");
 1980                 goto free_xs;
 1981         }
 1982 
 1983  restarted:
 1984         scsipi_run_queue(chan);
 1985 
 1986         /*
 1987          * The xfer is enqueued, and possibly running.  If it's to be
 1988          * completed asynchronously, just return now.
 1989          */
 1990         if (async)
 1991                 return (0);
 1992 
 1993         /*
 1994          * Not an asynchronous command; wait for it to complete.
 1995          */
 1996         s = splbio();
 1997         while ((xs->xs_status & XS_STS_DONE) == 0) {
 1998                 if (poll) {
 1999                         scsipi_printaddr(periph);
 2000                         printf("polling command not done\n");
 2001                         panic("scsipi_execute_xs");
 2002                 }
 2003                 (void) tsleep(xs, PRIBIO, "xscmd", 0);
 2004         }
 2005         splx(s);
 2006 
 2007         /*
 2008          * Command is complete.  scsipi_done() has awakened us to perform
 2009          * the error handling.
 2010          */
 2011         error = scsipi_complete(xs);
 2012         if (error == ERESTART)
 2013                 goto restarted;
 2014 
 2015         /*
 2016          * If it was meant to run async and we cleared aync ourselve,
 2017          * don't return an error here. It has already been handled
 2018          */
 2019         if (oasync)
 2020                 error = 0;
 2021         /*
 2022          * Command completed successfully or fatal error occurred.  Fall
 2023          * into....
 2024          */
 2025  free_xs:
 2026         if (xs->xs_control & XS_CTL_DATA_ONSTACK)
 2027                 uvm_lwp_rele(curlwp);
 2028 
 2029         s = splbio();
 2030         scsipi_put_xs(xs);
 2031         splx(s);
 2032 
 2033         /*
 2034          * Kick the queue, keep it running in case it stopped for some
 2035          * reason.
 2036          */
 2037         scsipi_run_queue(chan);
 2038 
 2039         return (error);
 2040 }
 2041 
 2042 /*
 2043  * scsipi_completion_thread:
 2044  *
 2045  *      This is the completion thread.  We wait for errors on
 2046  *      asynchronous xfers, and perform the error handling
 2047  *      function, restarting the command, if necessary.
 2048  */
 2049 static void
 2050 scsipi_completion_thread(void *arg)
 2051 {
 2052         struct scsipi_channel *chan = arg;
 2053         struct scsipi_xfer *xs;
 2054         int s;
 2055 
 2056         if (chan->chan_init_cb)
 2057                 (*chan->chan_init_cb)(chan, chan->chan_init_cb_arg);
 2058 
 2059         s = splbio();
 2060         chan->chan_flags |= SCSIPI_CHAN_TACTIVE;
 2061         splx(s);
 2062         for (;;) {
 2063                 s = splbio();
 2064                 xs = TAILQ_FIRST(&chan->chan_complete);
 2065                 if (xs == NULL && chan->chan_tflags  == 0) {
 2066                         /* nothing to do; wait */
 2067                         (void) tsleep(&chan->chan_complete, PRIBIO,
 2068                             "sccomp", 0);
 2069                         splx(s);
 2070                         continue;
 2071                 }
 2072                 if (chan->chan_tflags & SCSIPI_CHANT_CALLBACK) {
 2073                         /* call chan_callback from thread context */
 2074                         chan->chan_tflags &= ~SCSIPI_CHANT_CALLBACK;
 2075                         chan->chan_callback(chan, chan->chan_callback_arg);
 2076                         splx(s);
 2077                         continue;
 2078                 }
 2079                 if (chan->chan_tflags & SCSIPI_CHANT_GROWRES) {
 2080                         /* attempt to get more openings for this channel */
 2081                         chan->chan_tflags &= ~SCSIPI_CHANT_GROWRES;
 2082                         scsipi_adapter_request(chan,
 2083                             ADAPTER_REQ_GROW_RESOURCES, NULL);
 2084                         scsipi_channel_thaw(chan, 1);
 2085                         splx(s);
 2086                         if (chan->chan_tflags & SCSIPI_CHANT_GROWRES)
 2087                                 kpause("scsizzz", FALSE, hz/10, NULL);
 2088                         continue;
 2089                 }
 2090                 if (chan->chan_tflags & SCSIPI_CHANT_KICK) {
 2091                         /* explicitly run the queues for this channel */
 2092                         chan->chan_tflags &= ~SCSIPI_CHANT_KICK;
 2093                         scsipi_run_queue(chan);
 2094                         splx(s);
 2095                         continue;
 2096                 }
 2097                 if (chan->chan_tflags & SCSIPI_CHANT_SHUTDOWN) {
 2098                         splx(s);
 2099                         break;
 2100                 }
 2101                 if (xs) {
 2102                         TAILQ_REMOVE(&chan->chan_complete, xs, channel_q);
 2103                         splx(s);
 2104 
 2105                         /*
 2106                          * Have an xfer with an error; process it.
 2107                          */
 2108                         (void) scsipi_complete(xs);
 2109 
 2110                         /*
 2111                          * Kick the queue; keep it running if it was stopped
 2112                          * for some reason.
 2113                          */
 2114                         scsipi_run_queue(chan);
 2115                 } else {
 2116                         splx(s);
 2117                 }
 2118         }
 2119 
 2120         chan->chan_thread = NULL;
 2121 
 2122         /* In case parent is waiting for us to exit. */
 2123         wakeup(&chan->chan_thread);
 2124 
 2125         kthread_exit(0);
 2126 }
 2127 /*
 2128  * scsipi_thread_call_callback:
 2129  *
 2130  *      request to call a callback from the completion thread
 2131  */
 2132 int
 2133 scsipi_thread_call_callback(struct scsipi_channel *chan,
 2134     void (*callback)(struct scsipi_channel *, void *), void *arg)
 2135 {
 2136         int s;
 2137 
 2138         s = splbio();
 2139         if ((chan->chan_flags & SCSIPI_CHAN_TACTIVE) == 0) {
 2140                 /* kernel thread doesn't exist yet */
 2141                 splx(s);
 2142                 return ESRCH;
 2143         }
 2144         if (chan->chan_tflags & SCSIPI_CHANT_CALLBACK) {
 2145                 splx(s);
 2146                 return EBUSY;
 2147         }
 2148         scsipi_channel_freeze(chan, 1);
 2149         chan->chan_callback = callback;
 2150         chan->chan_callback_arg = arg;
 2151         chan->chan_tflags |= SCSIPI_CHANT_CALLBACK;
 2152         wakeup(&chan->chan_complete);
 2153         splx(s);
 2154         return(0);
 2155 }
 2156 
 2157 /*
 2158  * scsipi_async_event:
 2159  *
 2160  *      Handle an asynchronous event from an adapter.
 2161  */
 2162 void
 2163 scsipi_async_event(struct scsipi_channel *chan, scsipi_async_event_t event,
 2164     void *arg)
 2165 {
 2166         int s;
 2167 
 2168         s = splbio();
 2169         switch (event) {
 2170         case ASYNC_EVENT_MAX_OPENINGS:
 2171                 scsipi_async_event_max_openings(chan,
 2172                     (struct scsipi_max_openings *)arg);
 2173                 break;
 2174 
 2175         case ASYNC_EVENT_XFER_MODE:
 2176                 scsipi_async_event_xfer_mode(chan,
 2177                     (struct scsipi_xfer_mode *)arg);
 2178                 break;
 2179         case ASYNC_EVENT_RESET:
 2180                 scsipi_async_event_channel_reset(chan);
 2181                 break;
 2182         }
 2183         splx(s);
 2184 }
 2185 
 2186 /*
 2187  * scsipi_print_xfer_mode:
 2188  *
 2189  *      Print a periph's capabilities.
 2190  */
 2191 void
 2192 scsipi_print_xfer_mode(struct scsipi_periph *periph)
 2193 {
 2194         int period, freq, speed, mbs;
 2195 
 2196         if ((periph->periph_flags & PERIPH_MODE_VALID) == 0)
 2197                 return;
 2198 
 2199         aprint_normal_dev(periph->periph_dev, "");
 2200         if (periph->periph_mode & (PERIPH_CAP_SYNC | PERIPH_CAP_DT)) {
 2201                 period = scsipi_sync_factor_to_period(periph->periph_period);
 2202                 aprint_normal("sync (%d.%02dns offset %d)",
 2203                     period / 100, period % 100, periph->periph_offset);
 2204         } else
 2205                 aprint_normal("async");
 2206 
 2207         if (periph->periph_mode & PERIPH_CAP_WIDE32)
 2208                 aprint_normal(", 32-bit");
 2209         else if (periph->periph_mode & (PERIPH_CAP_WIDE16 | PERIPH_CAP_DT))
 2210                 aprint_normal(", 16-bit");
 2211         else
 2212                 aprint_normal(", 8-bit");
 2213 
 2214         if (periph->periph_mode & (PERIPH_CAP_SYNC | PERIPH_CAP_DT)) {
 2215                 freq = scsipi_sync_factor_to_freq(periph->periph_period);
 2216                 speed = freq;
 2217                 if (periph->periph_mode & PERIPH_CAP_WIDE32)
 2218                         speed *= 4;
 2219                 else if (periph->periph_mode &
 2220                     (PERIPH_CAP_WIDE16 | PERIPH_CAP_DT))
 2221                         speed *= 2;
 2222                 mbs = speed / 1000;
 2223                 if (mbs > 0)
 2224                         aprint_normal(" (%d.%03dMB/s)", mbs, speed % 1000);
 2225                 else
 2226                         aprint_normal(" (%dKB/s)", speed % 1000);
 2227         }
 2228 
 2229         aprint_normal(" transfers");
 2230 
 2231         if (periph->periph_mode & PERIPH_CAP_TQING)
 2232                 aprint_normal(", tagged queueing");
 2233 
 2234         aprint_normal("\n");
 2235 }
 2236 
 2237 /*
 2238  * scsipi_async_event_max_openings:
 2239  *
 2240  *      Update the maximum number of outstanding commands a
 2241  *      device may have.
 2242  */
 2243 static void
 2244 scsipi_async_event_max_openings(struct scsipi_channel *chan,
 2245     struct scsipi_max_openings *mo)
 2246 {
 2247         struct scsipi_periph *periph;
 2248         int minlun, maxlun;
 2249 
 2250         if (mo->mo_lun == -1) {
 2251                 /*
 2252                  * Wildcarded; apply it to all LUNs.
 2253                  */
 2254                 minlun = 0;
 2255                 maxlun = chan->chan_nluns - 1;
 2256         } else
 2257                 minlun = maxlun = mo->mo_lun;
 2258 
 2259         /* XXX This could really suck with a large LUN space. */
 2260         for (; minlun <= maxlun; minlun++) {
 2261                 periph = scsipi_lookup_periph(chan, mo->mo_target, minlun);
 2262                 if (periph == NULL)
 2263                         continue;
 2264 
 2265                 if (mo->mo_openings < periph->periph_openings)
 2266                         periph->periph_openings = mo->mo_openings;
 2267                 else if (mo->mo_openings > periph->periph_openings &&
 2268                     (periph->periph_flags & PERIPH_GROW_OPENINGS) != 0)
 2269                         periph->periph_openings = mo->mo_openings;
 2270         }
 2271 }
 2272 
 2273 /*
 2274  * scsipi_async_event_xfer_mode:
 2275  *
 2276  *      Update the xfer mode for all periphs sharing the
 2277  *      specified I_T Nexus.
 2278  */
 2279 static void
 2280 scsipi_async_event_xfer_mode(struct scsipi_channel *chan,
 2281     struct scsipi_xfer_mode *xm)
 2282 {
 2283         struct scsipi_periph *periph;
 2284         int lun, announce, mode, period, offset;
 2285 
 2286         for (lun = 0; lun < chan->chan_nluns; lun++) {
 2287                 periph = scsipi_lookup_periph(chan, xm->xm_target, lun);
 2288                 if (periph == NULL)
 2289                         continue;
 2290                 announce = 0;
 2291 
 2292                 /*
 2293                  * Clamp the xfer mode down to this periph's capabilities.
 2294                  */
 2295                 mode = xm->xm_mode & periph->periph_cap;
 2296                 if (mode & PERIPH_CAP_SYNC) {
 2297                         period = xm->xm_period;
 2298                         offset = xm->xm_offset;
 2299                 } else {
 2300                         period = 0;
 2301                         offset = 0;
 2302                 }
 2303 
 2304                 /*
 2305                  * If we do not have a valid xfer mode yet, or the parameters
 2306                  * are different, announce them.
 2307                  */
 2308                 if ((periph->periph_flags & PERIPH_MODE_VALID) == 0 ||
 2309                     periph->periph_mode != mode ||
 2310                     periph->periph_period != period ||
 2311                     periph->periph_offset != offset)
 2312                         announce = 1;
 2313 
 2314                 periph->periph_mode = mode;
 2315                 periph->periph_period = period;
 2316                 periph->periph_offset = offset;
 2317                 periph->periph_flags |= PERIPH_MODE_VALID;
 2318 
 2319                 if (announce)
 2320                         scsipi_print_xfer_mode(periph);
 2321         }
 2322 }
 2323 
 2324 /*
 2325  * scsipi_set_xfer_mode:
 2326  *
 2327  *      Set the xfer mode for the specified I_T Nexus.
 2328  */
 2329 void
 2330 scsipi_set_xfer_mode(struct scsipi_channel *chan, int target, int immed)
 2331 {
 2332         struct scsipi_xfer_mode xm;
 2333         struct scsipi_periph *itperiph;
 2334         int lun, s;
 2335 
 2336         /*
 2337          * Go to the minimal xfer mode.
 2338          */
 2339         xm.xm_target = target;
 2340         xm.xm_mode = 0;
 2341         xm.xm_period = 0;                       /* ignored */
 2342         xm.xm_offset = 0;                       /* ignored */
 2343 
 2344         /*
 2345          * Find the first LUN we know about on this I_T Nexus.
 2346          */
 2347         for (itperiph = NULL, lun = 0; lun < chan->chan_nluns; lun++) {
 2348                 itperiph = scsipi_lookup_periph(chan, target, lun);
 2349                 if (itperiph != NULL)
 2350                         break;
 2351         }
 2352         if (itperiph != NULL) {
 2353                 xm.xm_mode = itperiph->periph_cap;
 2354                 /*
 2355                  * Now issue the request to the adapter.
 2356                  */
 2357                 s = splbio();
 2358                 scsipi_adapter_request(chan, ADAPTER_REQ_SET_XFER_MODE, &xm);
 2359                 splx(s);
 2360                 /*
 2361                  * If we want this to happen immediately, issue a dummy
 2362                  * command, since most adapters can't really negotiate unless
 2363                  * they're executing a job.
 2364                  */
 2365                 if (immed != 0) {
 2366                         (void) scsipi_test_unit_ready(itperiph,
 2367                             XS_CTL_DISCOVERY | XS_CTL_IGNORE_ILLEGAL_REQUEST |
 2368                             XS_CTL_IGNORE_NOT_READY |
 2369                             XS_CTL_IGNORE_MEDIA_CHANGE);
 2370                 }
 2371         }
 2372 }
 2373 
 2374 /*
 2375  * scsipi_channel_reset:
 2376  *
 2377  *      handle scsi bus reset
 2378  * called at splbio
 2379  */
 2380 static void
 2381 scsipi_async_event_channel_reset(struct scsipi_channel *chan)
 2382 {
 2383         struct scsipi_xfer *xs, *xs_next;
 2384         struct scsipi_periph *periph;
 2385         int target, lun;
 2386 
 2387         /*
 2388          * Channel has been reset. Also mark as reset pending REQUEST_SENSE
 2389          * commands; as the sense is not available any more.
 2390          * can't call scsipi_done() from here, as the command has not been
 2391          * sent to the adapter yet (this would corrupt accounting).
 2392          */
 2393 
 2394         for (xs = TAILQ_FIRST(&chan->chan_queue); xs != NULL; xs = xs_next) {
 2395                 xs_next = TAILQ_NEXT(xs, channel_q);
 2396                 if (xs->xs_control & XS_CTL_REQSENSE) {
 2397                         TAILQ_REMOVE(&chan->chan_queue, xs, channel_q);
 2398                         xs->error = XS_RESET;
 2399                         if ((xs->xs_control & XS_CTL_ASYNC) != 0)
 2400                                 TAILQ_INSERT_TAIL(&chan->chan_complete, xs,
 2401                                     channel_q);
 2402                 }
 2403         }
 2404         wakeup(&chan->chan_complete);
 2405         /* Catch xs with pending sense which may not have a REQSENSE xs yet */
 2406         for (target = 0; target < chan->chan_ntargets; target++) {
 2407                 if (target == chan->chan_id)
 2408                         continue;
 2409                 for (lun = 0; lun <  chan->chan_nluns; lun++) {
 2410                         periph = scsipi_lookup_periph(chan, target, lun);
 2411                         if (periph) {
 2412                                 xs = periph->periph_xscheck;
 2413                                 if (xs)
 2414                                         xs->error = XS_RESET;
 2415                         }
 2416                 }
 2417         }
 2418 }
 2419 
 2420 /*
 2421  * scsipi_target_detach:
 2422  *
 2423  *      detach all periph associated with a I_T
 2424  *      must be called from valid thread context
 2425  */
 2426 int
 2427 scsipi_target_detach(struct scsipi_channel *chan, int target, int lun,
 2428     int flags)
 2429 {
 2430         struct scsipi_periph *periph;
 2431         int ctarget, mintarget, maxtarget;
 2432         int clun, minlun, maxlun;
 2433         int error;
 2434 
 2435         if (target == -1) {
 2436                 mintarget = 0;
 2437                 maxtarget = chan->chan_ntargets;
 2438         } else {
 2439                 if (target == chan->chan_id)
 2440                         return EINVAL;
 2441                 if (target < 0 || target >= chan->chan_ntargets)
 2442                         return EINVAL;
 2443                 mintarget = target;
 2444                 maxtarget = target + 1;
 2445         }
 2446 
 2447         if (lun == -1) {
 2448                 minlun = 0;
 2449                 maxlun = chan->chan_nluns;
 2450         } else {
 2451                 if (lun < 0 || lun >= chan->chan_nluns)
 2452                         return EINVAL;
 2453                 minlun = lun;
 2454                 maxlun = lun + 1;
 2455         }
 2456 
 2457         for (ctarget = mintarget; ctarget < maxtarget; ctarget++) {
 2458                 if (ctarget == chan->chan_id)
 2459                         continue;
 2460 
 2461                 for (clun = minlun; clun < maxlun; clun++) {
 2462                         periph = scsipi_lookup_periph(chan, ctarget, clun);
 2463                         if (periph == NULL)
 2464                                 continue;
 2465                         error = config_detach(periph->periph_dev, flags);
 2466                         if (error)
 2467                                 return (error);
 2468                 }
 2469         }
 2470         return(0);
 2471 }
 2472 
 2473 /*
 2474  * scsipi_adapter_addref:
 2475  *
 2476  *      Add a reference to the adapter pointed to by the provided
 2477  *      link, enabling the adapter if necessary.
 2478  */
 2479 int
 2480 scsipi_adapter_addref(struct scsipi_adapter *adapt)
 2481 {
 2482         int s, error = 0;
 2483 
 2484         s = splbio();
 2485         if (adapt->adapt_refcnt++ == 0 && adapt->adapt_enable != NULL) {
 2486                 error = (*adapt->adapt_enable)(adapt->adapt_dev, 1);
 2487                 if (error)
 2488                         adapt->adapt_refcnt--;
 2489         }
 2490         splx(s);
 2491         return (error);
 2492 }
 2493 
 2494 /*
 2495  * scsipi_adapter_delref:
 2496  *
 2497  *      Delete a reference to the adapter pointed to by the provided
 2498  *      link, disabling the adapter if possible.
 2499  */
 2500 void
 2501 scsipi_adapter_delref(struct scsipi_adapter *adapt)
 2502 {
 2503         int s;
 2504 
 2505         s = splbio();
 2506         if (adapt->adapt_refcnt-- == 1 && adapt->adapt_enable != NULL)
 2507                 (void) (*adapt->adapt_enable)(adapt->adapt_dev, 0);
 2508         splx(s);
 2509 }
 2510 
 2511 static struct scsipi_syncparam {
 2512         int     ss_factor;
 2513         int     ss_period;      /* ns * 100 */
 2514 } scsipi_syncparams[] = {
 2515         { 0x08,          625 }, /* FAST-160 (Ultra320) */
 2516         { 0x09,         1250 }, /* FAST-80 (Ultra160) */
 2517         { 0x0a,         2500 }, /* FAST-40 40MHz (Ultra2) */
 2518         { 0x0b,         3030 }, /* FAST-40 33MHz (Ultra2) */
 2519         { 0x0c,         5000 }, /* FAST-20 (Ultra) */
 2520 };
 2521 static const int scsipi_nsyncparams =
 2522     sizeof(scsipi_syncparams) / sizeof(scsipi_syncparams[0]);
 2523 
 2524 int
 2525 scsipi_sync_period_to_factor(int period /* ns * 100 */)
 2526 {
 2527         int i;
 2528 
 2529         for (i = 0; i < scsipi_nsyncparams; i++) {
 2530                 if (period <= scsipi_syncparams[i].ss_period)
 2531                         return (scsipi_syncparams[i].ss_factor);
 2532         }
 2533 
 2534         return ((period / 100) / 4);
 2535 }
 2536 
 2537 int
 2538 scsipi_sync_factor_to_period(int factor)
 2539 {
 2540         int i;
 2541 
 2542         for (i = 0; i < scsipi_nsyncparams; i++) {
 2543                 if (factor == scsipi_syncparams[i].ss_factor)
 2544                         return (scsipi_syncparams[i].ss_period);
 2545         }
 2546 
 2547         return ((factor * 4) * 100);
 2548 }
 2549 
 2550 int
 2551 scsipi_sync_factor_to_freq(int factor)
 2552 {
 2553         int i;
 2554 
 2555         for (i = 0; i < scsipi_nsyncparams; i++) {
 2556                 if (factor == scsipi_syncparams[i].ss_factor)
 2557                         return (100000000 / scsipi_syncparams[i].ss_period);
 2558         }
 2559 
 2560         return (10000000 / ((factor * 4) * 10));
 2561 }
 2562 
 2563 #ifdef SCSIPI_DEBUG
 2564 /*
 2565  * Given a scsipi_xfer, dump the request, in all it's glory
 2566  */
 2567 void
 2568 show_scsipi_xs(struct scsipi_xfer *xs)
 2569 {
 2570 
 2571         printf("xs(%p): ", xs);
 2572         printf("xs_control(0x%08x)", xs->xs_control);
 2573         printf("xs_status(0x%08x)", xs->xs_status);
 2574         printf("periph(%p)", xs->xs_periph);
 2575         printf("retr(0x%x)", xs->xs_retries);
 2576         printf("timo(0x%x)", xs->timeout);
 2577         printf("cmd(%p)", xs->cmd);
 2578         printf("len(0x%x)", xs->cmdlen);
 2579         printf("data(%p)", xs->data);
 2580         printf("len(0x%x)", xs->datalen);
 2581         printf("res(0x%x)", xs->resid);
 2582         printf("err(0x%x)", xs->error);
 2583         printf("bp(%p)", xs->bp);
 2584         show_scsipi_cmd(xs);
 2585 }
 2586 
 2587 void
 2588 show_scsipi_cmd(struct scsipi_xfer *xs)
 2589 {
 2590         u_char *b = (u_char *) xs->cmd;
 2591         int i = 0;
 2592 
 2593         scsipi_printaddr(xs->xs_periph);
 2594         printf(" command: ");
 2595 
 2596         if ((xs->xs_control & XS_CTL_RESET) == 0) {
 2597                 while (i < xs->cmdlen) {
 2598                         if (i)
 2599                                 printf(",");
 2600                         printf("0x%x", b[i++]);
 2601                 }
 2602                 printf("-[%d bytes]\n", xs->datalen);
 2603                 if (xs->datalen)
 2604                         show_mem(xs->data, min(64, xs->datalen));
 2605         } else
 2606                 printf("-RESET-\n");
 2607 }
 2608 
 2609 void
 2610 show_mem(u_char *address, int num)
 2611 {
 2612         int x;
 2613 
 2614         printf("------------------------------");
 2615         for (x = 0; x < num; x++) {
 2616                 if ((x % 16) == 0)
 2617                         printf("\n%03d: ", x);
 2618                 printf("%02x ", *address++);
 2619         }
 2620         printf("\n------------------------------\n");
 2621 }
 2622 #endif /* SCSIPI_DEBUG */

Cache object: 143ed0241d2e8278d2795bbd0bc87526


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