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.142 2006/11/26 05:01:09 itohy 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  * 3. All advertising materials mentioning features or use of this software
   20  *    must display the following acknowledgement:
   21  *        This product includes software developed by the NetBSD
   22  *        Foundation, Inc. and its contributors.
   23  * 4. Neither the name of The NetBSD Foundation nor the names of its
   24  *    contributors may be used to endorse or promote products derived
   25  *    from this software without specific prior written permission.
   26  *
   27  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   28  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   29  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   30  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   31  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   32  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   33  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   34  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   35  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   36  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   37  * POSSIBILITY OF SUCH DAMAGE.
   38  */
   39 
   40 #include <sys/cdefs.h>
   41 __KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.142 2006/11/26 05:01:09 itohy Exp $");
   42 
   43 #include "opt_scsi.h"
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/kernel.h>
   48 #include <sys/buf.h>
   49 #include <sys/uio.h>
   50 #include <sys/malloc.h>
   51 #include <sys/pool.h>
   52 #include <sys/errno.h>
   53 #include <sys/device.h>
   54 #include <sys/proc.h>
   55 #include <sys/kthread.h>
   56 #include <sys/hash.h>
   57 
   58 #include <uvm/uvm_extern.h>
   59 
   60 #include <dev/scsipi/scsi_spc.h>
   61 #include <dev/scsipi/scsipi_all.h>
   62 #include <dev/scsipi/scsipi_disk.h>
   63 #include <dev/scsipi/scsipiconf.h>
   64 #include <dev/scsipi/scsipi_base.h>
   65 
   66 #include <dev/scsipi/scsi_all.h>
   67 #include <dev/scsipi/scsi_message.h>
   68 
   69 static int      scsipi_complete(struct scsipi_xfer *);
   70 static void     scsipi_request_sense(struct scsipi_xfer *);
   71 static int      scsipi_enqueue(struct scsipi_xfer *);
   72 static void     scsipi_run_queue(struct scsipi_channel *chan);
   73 
   74 static void     scsipi_completion_thread(void *);
   75 
   76 static void     scsipi_get_tag(struct scsipi_xfer *);
   77 static void     scsipi_put_tag(struct scsipi_xfer *);
   78 
   79 static int      scsipi_get_resource(struct scsipi_channel *);
   80 static void     scsipi_put_resource(struct scsipi_channel *);
   81 
   82 static void     scsipi_async_event_max_openings(struct scsipi_channel *,
   83                     struct scsipi_max_openings *);
   84 static void     scsipi_async_event_xfer_mode(struct scsipi_channel *,
   85                     struct scsipi_xfer_mode *);
   86 static void     scsipi_async_event_channel_reset(struct scsipi_channel *);
   87 
   88 static struct pool scsipi_xfer_pool;
   89 
   90 /*
   91  * scsipi_init:
   92  *
   93  *      Called when a scsibus or atapibus is attached to the system
   94  *      to initialize shared data structures.
   95  */
   96 void
   97 scsipi_init(void)
   98 {
   99         static int scsipi_init_done;
  100 
  101         if (scsipi_init_done)
  102                 return;
  103         scsipi_init_done = 1;
  104 
  105         /* Initialize the scsipi_xfer pool. */
  106         pool_init(&scsipi_xfer_pool, sizeof(struct scsipi_xfer), 0,
  107             0, 0, "scxspl", NULL);
  108         if (pool_prime(&scsipi_xfer_pool,
  109             PAGE_SIZE / sizeof(struct scsipi_xfer)) == ENOMEM) {
  110                 printf("WARNING: not enough memory for scsipi_xfer_pool\n");
  111         }
  112 }
  113 
  114 /*
  115  * scsipi_channel_init:
  116  *
  117  *      Initialize a scsipi_channel when it is attached.
  118  */
  119 int
  120 scsipi_channel_init(struct scsipi_channel *chan)
  121 {
  122         int i;
  123 
  124         /* Initialize shared data. */
  125         scsipi_init();
  126 
  127         /* Initialize the queues. */
  128         TAILQ_INIT(&chan->chan_queue);
  129         TAILQ_INIT(&chan->chan_complete);
  130 
  131         for (i = 0; i < SCSIPI_CHAN_PERIPH_BUCKETS; i++)
  132                 LIST_INIT(&chan->chan_periphtab[i]);
  133 
  134         /*
  135          * Create the asynchronous completion thread.
  136          */
  137         kthread_create(scsipi_create_completion_thread, chan);
  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);
  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         memset(&cmd, 0, sizeof(cmd));
 1154         cmd.opcode = SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL;
 1155         cmd.how = type;
 1156 
 1157         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd), 0, 0,
 1158             SCSIPIRETRIES, 5000, NULL, flags));
 1159 }
 1160 
 1161 /*
 1162  * scsipi_start:
 1163  *
 1164  *      Send a START UNIT.
 1165  */
 1166 int
 1167 scsipi_start(struct scsipi_periph *periph, int type, int flags)
 1168 {
 1169         struct scsipi_start_stop cmd;
 1170 
 1171         memset(&cmd, 0, sizeof(cmd));
 1172         cmd.opcode = START_STOP;
 1173         cmd.byte2 = 0x00;
 1174         cmd.how = type;
 1175 
 1176         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd), 0, 0,
 1177             SCSIPIRETRIES, (type & SSS_START) ? 60000 : 10000, NULL, flags));
 1178 }
 1179 
 1180 /*
 1181  * scsipi_mode_sense, scsipi_mode_sense_big:
 1182  *      get a sense page from a device
 1183  */
 1184 
 1185 int
 1186 scsipi_mode_sense(struct scsipi_periph *periph, int byte2, int page,
 1187     struct scsi_mode_parameter_header_6 *data, int len, int flags, int retries,
 1188     int timeout)
 1189 {
 1190         struct scsi_mode_sense_6 cmd;
 1191 
 1192         memset(&cmd, 0, sizeof(cmd));
 1193         cmd.opcode = SCSI_MODE_SENSE_6;
 1194         cmd.byte2 = byte2;
 1195         cmd.page = page;
 1196         cmd.length = len & 0xff;
 1197 
 1198         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1199             (void *)data, len, retries, timeout, NULL, flags | XS_CTL_DATA_IN));
 1200 }
 1201 
 1202 int
 1203 scsipi_mode_sense_big(struct scsipi_periph *periph, int byte2, int page,
 1204     struct scsi_mode_parameter_header_10 *data, int len, int flags, int retries,
 1205     int timeout)
 1206 {
 1207         struct scsi_mode_sense_10 cmd;
 1208 
 1209         memset(&cmd, 0, sizeof(cmd));
 1210         cmd.opcode = SCSI_MODE_SENSE_10;
 1211         cmd.byte2 = byte2;
 1212         cmd.page = page;
 1213         _lto2b(len, cmd.length);
 1214 
 1215         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1216             (void *)data, len, retries, timeout, NULL, flags | XS_CTL_DATA_IN));
 1217 }
 1218 
 1219 int
 1220 scsipi_mode_select(struct scsipi_periph *periph, int byte2,
 1221     struct scsi_mode_parameter_header_6 *data, int len, int flags, int retries,
 1222     int timeout)
 1223 {
 1224         struct scsi_mode_select_6 cmd;
 1225 
 1226         memset(&cmd, 0, sizeof(cmd));
 1227         cmd.opcode = SCSI_MODE_SELECT_6;
 1228         cmd.byte2 = byte2;
 1229         cmd.length = len & 0xff;
 1230 
 1231         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1232             (void *)data, len, retries, timeout, NULL, flags | XS_CTL_DATA_OUT));
 1233 }
 1234 
 1235 int
 1236 scsipi_mode_select_big(struct scsipi_periph *periph, int byte2,
 1237     struct scsi_mode_parameter_header_10 *data, int len, int flags, int retries,
 1238     int timeout)
 1239 {
 1240         struct scsi_mode_select_10 cmd;
 1241 
 1242         memset(&cmd, 0, sizeof(cmd));
 1243         cmd.opcode = SCSI_MODE_SELECT_10;
 1244         cmd.byte2 = byte2;
 1245         _lto2b(len, cmd.length);
 1246 
 1247         return (scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1248             (void *)data, len, retries, timeout, NULL, flags | XS_CTL_DATA_OUT));
 1249 }
 1250 
 1251 /*
 1252  * scsipi_done:
 1253  *
 1254  *      This routine is called by an adapter's interrupt handler when
 1255  *      an xfer is completed.
 1256  */
 1257 void
 1258 scsipi_done(struct scsipi_xfer *xs)
 1259 {
 1260         struct scsipi_periph *periph = xs->xs_periph;
 1261         struct scsipi_channel *chan = periph->periph_channel;
 1262         int s, freezecnt;
 1263 
 1264         SC_DEBUG(periph, SCSIPI_DB2, ("scsipi_done\n"));
 1265 #ifdef SCSIPI_DEBUG
 1266         if (periph->periph_dbflags & SCSIPI_DB1)
 1267                 show_scsipi_cmd(xs);
 1268 #endif
 1269 
 1270         s = splbio();
 1271         /*
 1272          * The resource this command was using is now free.
 1273          */
 1274         if (xs->xs_status & XS_STS_DONE) {
 1275                 /* XXX in certain circumstances, such as a device
 1276                  * being detached, a xs that has already been
 1277                  * scsipi_done()'d by the main thread will be done'd
 1278                  * again by scsibusdetach(). Putting the xs on the
 1279                  * chan_complete queue causes list corruption and
 1280                  * everyone dies. This prevents that, but perhaps
 1281                  * there should be better coordination somewhere such
 1282                  * that this won't ever happen (and can be turned into
 1283                  * a KASSERT().
 1284                  */
 1285                 splx(s);
 1286                 goto out;
 1287         }
 1288         scsipi_put_resource(chan);
 1289         xs->xs_periph->periph_sent--;
 1290 
 1291         /*
 1292          * If the command was tagged, free the tag.
 1293          */
 1294         if (XS_CTL_TAGTYPE(xs) != 0)
 1295                 scsipi_put_tag(xs);
 1296         else
 1297                 periph->periph_flags &= ~PERIPH_UNTAG;
 1298 
 1299         /* Mark the command as `done'. */
 1300         xs->xs_status |= XS_STS_DONE;
 1301 
 1302 #ifdef DIAGNOSTIC
 1303         if ((xs->xs_control & (XS_CTL_ASYNC|XS_CTL_POLL)) ==
 1304             (XS_CTL_ASYNC|XS_CTL_POLL))
 1305                 panic("scsipi_done: ASYNC and POLL");
 1306 #endif
 1307 
 1308         /*
 1309          * If the xfer had an error of any sort, freeze the
 1310          * periph's queue.  Freeze it again if we were requested
 1311          * to do so in the xfer.
 1312          */
 1313         freezecnt = 0;
 1314         if (xs->error != XS_NOERROR)
 1315                 freezecnt++;
 1316         if (xs->xs_control & XS_CTL_FREEZE_PERIPH)
 1317                 freezecnt++;
 1318         if (freezecnt != 0)
 1319                 scsipi_periph_freeze(periph, freezecnt);
 1320 
 1321         /*
 1322          * record the xfer with a pending sense, in case a SCSI reset is
 1323          * received before the thread is waked up.
 1324          */
 1325         if (xs->error == XS_BUSY && xs->status == SCSI_CHECK) {
 1326                 periph->periph_flags |= PERIPH_SENSE;
 1327                 periph->periph_xscheck = xs;
 1328         }
 1329 
 1330         /*
 1331          * If this was an xfer that was not to complete asynchronously,
 1332          * let the requesting thread perform error checking/handling
 1333          * in its context.
 1334          */
 1335         if ((xs->xs_control & XS_CTL_ASYNC) == 0) {
 1336                 splx(s);
 1337                 /*
 1338                  * If it's a polling job, just return, to unwind the
 1339                  * call graph.  We don't need to restart the queue,
 1340                  * because pollings jobs are treated specially, and
 1341                  * are really only used during crash dumps anyway
 1342                  * (XXX or during boot-time autconfiguration of
 1343                  * ATAPI devices).
 1344                  */
 1345                 if (xs->xs_control & XS_CTL_POLL)
 1346                         return;
 1347                 wakeup(xs);
 1348                 goto out;
 1349         }
 1350 
 1351         /*
 1352          * Catch the extremely common case of I/O completing
 1353          * without error; no use in taking a context switch
 1354          * if we can handle it in interrupt context.
 1355          */
 1356         if (xs->error == XS_NOERROR) {
 1357                 splx(s);
 1358                 (void) scsipi_complete(xs);
 1359                 goto out;
 1360         }
 1361 
 1362         /*
 1363          * There is an error on this xfer.  Put it on the channel's
 1364          * completion queue, and wake up the completion thread.
 1365          */
 1366         TAILQ_INSERT_TAIL(&chan->chan_complete, xs, channel_q);
 1367         splx(s);
 1368         wakeup(&chan->chan_complete);
 1369 
 1370  out:
 1371         /*
 1372          * If there are more xfers on the channel's queue, attempt to
 1373          * run them.
 1374          */
 1375         scsipi_run_queue(chan);
 1376 }
 1377 
 1378 /*
 1379  * scsipi_complete:
 1380  *
 1381  *      Completion of a scsipi_xfer.  This is the guts of scsipi_done().
 1382  *
 1383  *      NOTE: This routine MUST be called with valid thread context
 1384  *      except for the case where the following two conditions are
 1385  *      true:
 1386  *
 1387  *              xs->error == XS_NOERROR
 1388  *              XS_CTL_ASYNC is set in xs->xs_control
 1389  *
 1390  *      The semantics of this routine can be tricky, so here is an
 1391  *      explanation:
 1392  *
 1393  *              0               Xfer completed successfully.
 1394  *
 1395  *              ERESTART        Xfer had an error, but was restarted.
 1396  *
 1397  *              anything else   Xfer had an error, return value is Unix
 1398  *                              errno.
 1399  *
 1400  *      If the return value is anything but ERESTART:
 1401  *
 1402  *              - If XS_CTL_ASYNC is set, `xs' has been freed back to
 1403  *                the pool.
 1404  *              - If there is a buf associated with the xfer,
 1405  *                it has been biodone()'d.
 1406  */
 1407 static int
 1408 scsipi_complete(struct scsipi_xfer *xs)
 1409 {
 1410         struct scsipi_periph *periph = xs->xs_periph;
 1411         struct scsipi_channel *chan = periph->periph_channel;
 1412         int error, s;
 1413 
 1414 #ifdef DIAGNOSTIC
 1415         if ((xs->xs_control & XS_CTL_ASYNC) != 0 && xs->bp == NULL)
 1416                 panic("scsipi_complete: XS_CTL_ASYNC but no buf");
 1417 #endif
 1418         /*
 1419          * If command terminated with a CHECK CONDITION, we need to issue a
 1420          * REQUEST_SENSE command. Once the REQUEST_SENSE has been processed
 1421          * we'll have the real status.
 1422          * Must be processed at splbio() to avoid missing a SCSI bus reset
 1423          * for this command.
 1424          */
 1425         s = splbio();
 1426         if (xs->error == XS_BUSY && xs->status == SCSI_CHECK) {
 1427                 /* request sense for a request sense ? */
 1428                 if (xs->xs_control & XS_CTL_REQSENSE) {
 1429                         scsipi_printaddr(periph);
 1430                         printf("request sense for a request sense ?\n");
 1431                         /* XXX maybe we should reset the device ? */
 1432                         /* we've been frozen because xs->error != XS_NOERROR */
 1433                         scsipi_periph_thaw(periph, 1);
 1434                         splx(s);
 1435                         if (xs->resid < xs->datalen) {
 1436                                 printf("we read %d bytes of sense anyway:\n",
 1437                                     xs->datalen - xs->resid);
 1438 #ifdef SCSIVERBOSE
 1439                                 scsipi_print_sense_data((void *)xs->data, 0);
 1440 #endif
 1441                         }
 1442                         return EINVAL;
 1443                 }
 1444                 scsipi_request_sense(xs);
 1445         }
 1446         splx(s);
 1447 
 1448         /*
 1449          * If it's a user level request, bypass all usual completion
 1450          * processing, let the user work it out..
 1451          */
 1452         if ((xs->xs_control & XS_CTL_USERCMD) != 0) {
 1453                 SC_DEBUG(periph, SCSIPI_DB3, ("calling user done()\n"));
 1454                 if (xs->error != XS_NOERROR)
 1455                         scsipi_periph_thaw(periph, 1);
 1456                 scsipi_user_done(xs);
 1457                 SC_DEBUG(periph, SCSIPI_DB3, ("returned from user done()\n "));
 1458                 return 0;
 1459         }
 1460 
 1461         switch (xs->error) {
 1462         case XS_NOERROR:
 1463                 error = 0;
 1464                 break;
 1465 
 1466         case XS_SENSE:
 1467         case XS_SHORTSENSE:
 1468                 error = (*chan->chan_bustype->bustype_interpret_sense)(xs);
 1469                 break;
 1470 
 1471         case XS_RESOURCE_SHORTAGE:
 1472                 /*
 1473                  * XXX Should freeze channel's queue.
 1474                  */
 1475                 scsipi_printaddr(periph);
 1476                 printf("adapter resource shortage\n");
 1477                 /* FALLTHROUGH */
 1478 
 1479         case XS_BUSY:
 1480                 if (xs->error == XS_BUSY && xs->status == SCSI_QUEUE_FULL) {
 1481                         struct scsipi_max_openings mo;
 1482 
 1483                         /*
 1484                          * We set the openings to active - 1, assuming that
 1485                          * the command that got us here is the first one that
 1486                          * can't fit into the device's queue.  If that's not
 1487                          * the case, I guess we'll find out soon enough.
 1488                          */
 1489                         mo.mo_target = periph->periph_target;
 1490                         mo.mo_lun = periph->periph_lun;
 1491                         if (periph->periph_active < periph->periph_openings)
 1492                                 mo.mo_openings = periph->periph_active - 1;
 1493                         else
 1494                                 mo.mo_openings = periph->periph_openings - 1;
 1495 #ifdef DIAGNOSTIC
 1496                         if (mo.mo_openings < 0) {
 1497                                 scsipi_printaddr(periph);
 1498                                 printf("QUEUE FULL resulted in < 0 openings\n");
 1499                                 panic("scsipi_done");
 1500                         }
 1501 #endif
 1502                         if (mo.mo_openings == 0) {
 1503                                 scsipi_printaddr(periph);
 1504                                 printf("QUEUE FULL resulted in 0 openings\n");
 1505                                 mo.mo_openings = 1;
 1506                         }
 1507                         scsipi_async_event(chan, ASYNC_EVENT_MAX_OPENINGS, &mo);
 1508                         error = ERESTART;
 1509                 } else if (xs->xs_retries != 0) {
 1510                         xs->xs_retries--;
 1511                         /*
 1512                          * Wait one second, and try again.
 1513                          */
 1514                         if ((xs->xs_control & XS_CTL_POLL) ||
 1515                             (chan->chan_flags & SCSIPI_CHAN_TACTIVE) == 0) {
 1516                                 delay(1000000);
 1517                         } else if (!callout_pending(&periph->periph_callout)) {
 1518                                 scsipi_periph_freeze(periph, 1);
 1519                                 callout_reset(&periph->periph_callout,
 1520                                     hz, scsipi_periph_timed_thaw, periph);
 1521                         }
 1522                         error = ERESTART;
 1523                 } else
 1524                         error = EBUSY;
 1525                 break;
 1526 
 1527         case XS_REQUEUE:
 1528                 error = ERESTART;
 1529                 break;
 1530 
 1531         case XS_SELTIMEOUT:
 1532         case XS_TIMEOUT:
 1533                 /*
 1534                  * If the device hasn't gone away, honor retry counts.
 1535                  *
 1536                  * Note that if we're in the middle of probing it,
 1537                  * it won't be found because it isn't here yet so
 1538                  * we won't honor the retry count in that case.
 1539                  */
 1540                 if (scsipi_lookup_periph(chan, periph->periph_target,
 1541                     periph->periph_lun) && xs->xs_retries != 0) {
 1542                         xs->xs_retries--;
 1543                         error = ERESTART;
 1544                 } else
 1545                         error = EIO;
 1546                 break;
 1547 
 1548         case XS_RESET:
 1549                 if (xs->xs_control & XS_CTL_REQSENSE) {
 1550                         /*
 1551                          * request sense interrupted by reset: signal it
 1552                          * with EINTR return code.
 1553                          */
 1554                         error = EINTR;
 1555                 } else {
 1556                         if (xs->xs_retries != 0) {
 1557                                 xs->xs_retries--;
 1558                                 error = ERESTART;
 1559                         } else
 1560                                 error = EIO;
 1561                 }
 1562                 break;
 1563 
 1564         case XS_DRIVER_STUFFUP:
 1565                 scsipi_printaddr(periph);
 1566                 printf("generic HBA error\n");
 1567                 error = EIO;
 1568                 break;
 1569         default:
 1570                 scsipi_printaddr(periph);
 1571                 printf("invalid return code from adapter: %d\n", xs->error);
 1572                 error = EIO;
 1573                 break;
 1574         }
 1575 
 1576         s = splbio();
 1577         if (error == ERESTART) {
 1578                 /*
 1579                  * If we get here, the periph has been thawed and frozen
 1580                  * again if we had to issue recovery commands.  Alternatively,
 1581                  * it may have been frozen again and in a timed thaw.  In
 1582                  * any case, we thaw the periph once we re-enqueue the
 1583                  * command.  Once the periph is fully thawed, it will begin
 1584                  * operation again.
 1585                  */
 1586                 xs->error = XS_NOERROR;
 1587                 xs->status = SCSI_OK;
 1588                 xs->xs_status &= ~XS_STS_DONE;
 1589                 xs->xs_requeuecnt++;
 1590                 error = scsipi_enqueue(xs);
 1591                 if (error == 0) {
 1592                         scsipi_periph_thaw(periph, 1);
 1593                         splx(s);
 1594                         return (ERESTART);
 1595                 }
 1596         }
 1597 
 1598         /*
 1599          * scsipi_done() freezes the queue if not XS_NOERROR.
 1600          * Thaw it here.
 1601          */
 1602         if (xs->error != XS_NOERROR)
 1603                 scsipi_periph_thaw(periph, 1);
 1604 
 1605         if (periph->periph_switch->psw_done)
 1606                 periph->periph_switch->psw_done(xs, error);
 1607 
 1608         if (xs->xs_control & XS_CTL_ASYNC)
 1609                 scsipi_put_xs(xs);
 1610         splx(s);
 1611 
 1612         return (error);
 1613 }
 1614 
 1615 /*
 1616  * Issue a request sense for the given scsipi_xfer. Called when the xfer
 1617  * returns with a CHECK_CONDITION status. Must be called in valid thread
 1618  * context and at splbio().
 1619  */
 1620 
 1621 static void
 1622 scsipi_request_sense(struct scsipi_xfer *xs)
 1623 {
 1624         struct scsipi_periph *periph = xs->xs_periph;
 1625         int flags, error;
 1626         struct scsi_request_sense cmd;
 1627 
 1628         periph->periph_flags |= PERIPH_SENSE;
 1629 
 1630         /* if command was polling, request sense will too */
 1631         flags = xs->xs_control & XS_CTL_POLL;
 1632         /* Polling commands can't sleep */
 1633         if (flags)
 1634                 flags |= XS_CTL_NOSLEEP;
 1635 
 1636         flags |= XS_CTL_REQSENSE | XS_CTL_URGENT | XS_CTL_DATA_IN |
 1637             XS_CTL_THAW_PERIPH | XS_CTL_FREEZE_PERIPH;
 1638 
 1639         memset(&cmd, 0, sizeof(cmd));
 1640         cmd.opcode = SCSI_REQUEST_SENSE;
 1641         cmd.length = sizeof(struct scsi_sense_data);
 1642 
 1643         error = scsipi_command(periph, (void *)&cmd, sizeof(cmd),
 1644             (void *)&xs->sense.scsi_sense, sizeof(struct scsi_sense_data),
 1645             0, 1000, NULL, flags);
 1646         periph->periph_flags &= ~PERIPH_SENSE;
 1647         periph->periph_xscheck = NULL;
 1648         switch (error) {
 1649         case 0:
 1650                 /* we have a valid sense */
 1651                 xs->error = XS_SENSE;
 1652                 return;
 1653         case EINTR:
 1654                 /* REQUEST_SENSE interrupted by bus reset. */
 1655                 xs->error = XS_RESET;
 1656                 return;
 1657         case EIO:
 1658                  /* request sense coudn't be performed */
 1659                 /*
 1660                  * XXX this isn't quite right but we don't have anything
 1661                  * better for now
 1662                  */
 1663                 xs->error = XS_DRIVER_STUFFUP;
 1664                 return;
 1665         default:
 1666                  /* Notify that request sense failed. */
 1667                 xs->error = XS_DRIVER_STUFFUP;
 1668                 scsipi_printaddr(periph);
 1669                 printf("request sense failed with error %d\n", error);
 1670                 return;
 1671         }
 1672 }
 1673 
 1674 /*
 1675  * scsipi_enqueue:
 1676  *
 1677  *      Enqueue an xfer on a channel.
 1678  */
 1679 static int
 1680 scsipi_enqueue(struct scsipi_xfer *xs)
 1681 {
 1682         struct scsipi_channel *chan = xs->xs_periph->periph_channel;
 1683         struct scsipi_xfer *qxs;
 1684         int s;
 1685 
 1686         s = splbio();
 1687 
 1688         /*
 1689          * If the xfer is to be polled, and there are already jobs on
 1690          * the queue, we can't proceed.
 1691          */
 1692         if ((xs->xs_control & XS_CTL_POLL) != 0 &&
 1693             TAILQ_FIRST(&chan->chan_queue) != NULL) {
 1694                 splx(s);
 1695                 xs->error = XS_DRIVER_STUFFUP;
 1696                 return (EAGAIN);
 1697         }
 1698 
 1699         /*
 1700          * If we have an URGENT xfer, it's an error recovery command
 1701          * and it should just go on the head of the channel's queue.
 1702          */
 1703         if (xs->xs_control & XS_CTL_URGENT) {
 1704                 TAILQ_INSERT_HEAD(&chan->chan_queue, xs, channel_q);
 1705                 goto out;
 1706         }
 1707 
 1708         /*
 1709          * If this xfer has already been on the queue before, we
 1710          * need to reinsert it in the correct order.  That order is:
 1711          *
 1712          *      Immediately before the first xfer for this periph
 1713          *      with a requeuecnt less than xs->xs_requeuecnt.
 1714          *
 1715          * Failing that, at the end of the queue.  (We'll end up
 1716          * there naturally.)
 1717          */
 1718         if (xs->xs_requeuecnt != 0) {
 1719                 for (qxs = TAILQ_FIRST(&chan->chan_queue); qxs != NULL;
 1720                      qxs = TAILQ_NEXT(qxs, channel_q)) {
 1721                         if (qxs->xs_periph == xs->xs_periph &&
 1722                             qxs->xs_requeuecnt < xs->xs_requeuecnt)
 1723                                 break;
 1724                 }
 1725                 if (qxs != NULL) {
 1726                         TAILQ_INSERT_AFTER(&chan->chan_queue, qxs, xs,
 1727                             channel_q);
 1728                         goto out;
 1729                 }
 1730         }
 1731         TAILQ_INSERT_TAIL(&chan->chan_queue, xs, channel_q);
 1732  out:
 1733         if (xs->xs_control & XS_CTL_THAW_PERIPH)
 1734                 scsipi_periph_thaw(xs->xs_periph, 1);
 1735         splx(s);
 1736         return (0);
 1737 }
 1738 
 1739 /*
 1740  * scsipi_run_queue:
 1741  *
 1742  *      Start as many xfers as possible running on the channel.
 1743  */
 1744 static void
 1745 scsipi_run_queue(struct scsipi_channel *chan)
 1746 {
 1747         struct scsipi_xfer *xs;
 1748         struct scsipi_periph *periph;
 1749         int s;
 1750 
 1751         for (;;) {
 1752                 s = splbio();
 1753 
 1754                 /*
 1755                  * If the channel is frozen, we can't do any work right
 1756                  * now.
 1757                  */
 1758                 if (chan->chan_qfreeze != 0) {
 1759                         splx(s);
 1760                         return;
 1761                 }
 1762 
 1763                 /*
 1764                  * Look for work to do, and make sure we can do it.
 1765                  */
 1766                 for (xs = TAILQ_FIRST(&chan->chan_queue); xs != NULL;
 1767                      xs = TAILQ_NEXT(xs, channel_q)) {
 1768                         periph = xs->xs_periph;
 1769 
 1770                         if ((periph->periph_sent >= periph->periph_openings) ||
 1771                             periph->periph_qfreeze != 0 ||
 1772                             (periph->periph_flags & PERIPH_UNTAG) != 0)
 1773                                 continue;
 1774 
 1775                         if ((periph->periph_flags &
 1776                             (PERIPH_RECOVERING | PERIPH_SENSE)) != 0 &&
 1777                             (xs->xs_control & XS_CTL_URGENT) == 0)
 1778                                 continue;
 1779 
 1780                         /*
 1781                          * We can issue this xfer!
 1782                          */
 1783                         goto got_one;
 1784                 }
 1785 
 1786                 /*
 1787                  * Can't find any work to do right now.
 1788                  */
 1789                 splx(s);
 1790                 return;
 1791 
 1792  got_one:
 1793                 /*
 1794                  * Have an xfer to run.  Allocate a resource from
 1795                  * the adapter to run it.  If we can't allocate that
 1796                  * resource, we don't dequeue the xfer.
 1797                  */
 1798                 if (scsipi_get_resource(chan) == 0) {
 1799                         /*
 1800                          * Adapter is out of resources.  If the adapter
 1801                          * supports it, attempt to grow them.
 1802                          */
 1803                         if (scsipi_grow_resources(chan) == 0) {
 1804                                 /*
 1805                                  * Wasn't able to grow resources,
 1806                                  * nothing more we can do.
 1807                                  */
 1808                                 if (xs->xs_control & XS_CTL_POLL) {
 1809                                         scsipi_printaddr(xs->xs_periph);
 1810                                         printf("polling command but no "
 1811                                             "adapter resources");
 1812                                         /* We'll panic shortly... */
 1813                                 }
 1814                                 splx(s);
 1815 
 1816                                 /*
 1817                                  * XXX: We should be able to note that
 1818                                  * XXX: that resources are needed here!
 1819                                  */
 1820                                 return;
 1821                         }
 1822                         /*
 1823                          * scsipi_grow_resources() allocated the resource
 1824                          * for us.
 1825                          */
 1826                 }
 1827 
 1828                 /*
 1829                  * We have a resource to run this xfer, do it!
 1830                  */
 1831                 TAILQ_REMOVE(&chan->chan_queue, xs, channel_q);
 1832 
 1833                 /*
 1834                  * If the command is to be tagged, allocate a tag ID
 1835                  * for it.
 1836                  */
 1837                 if (XS_CTL_TAGTYPE(xs) != 0)
 1838                         scsipi_get_tag(xs);
 1839                 else
 1840                         periph->periph_flags |= PERIPH_UNTAG;
 1841                 periph->periph_sent++;
 1842                 splx(s);
 1843 
 1844                 scsipi_adapter_request(chan, ADAPTER_REQ_RUN_XFER, xs);
 1845         }
 1846 #ifdef DIAGNOSTIC
 1847         panic("scsipi_run_queue: impossible");
 1848 #endif
 1849 }
 1850 
 1851 /*
 1852  * scsipi_execute_xs:
 1853  *
 1854  *      Begin execution of an xfer, waiting for it to complete, if necessary.
 1855  */
 1856 int
 1857 scsipi_execute_xs(struct scsipi_xfer *xs)
 1858 {
 1859         struct scsipi_periph *periph = xs->xs_periph;
 1860         struct scsipi_channel *chan = periph->periph_channel;
 1861         int oasync, async, poll, error, s;
 1862 
 1863         KASSERT(!cold);
 1864 
 1865         (chan->chan_bustype->bustype_cmd)(xs);
 1866 
 1867         if (xs->xs_control & XS_CTL_DATA_ONSTACK) {
 1868 #if 1
 1869                 if (xs->xs_control & XS_CTL_ASYNC)
 1870                         panic("scsipi_execute_xs: on stack and async");
 1871 #endif
 1872                 /*
 1873                  * If the I/O buffer is allocated on stack, the
 1874                  * process must NOT be swapped out, as the device will
 1875                  * be accessing the stack.
 1876                  */
 1877                 PHOLD(curlwp);
 1878         }
 1879 
 1880         xs->xs_status &= ~XS_STS_DONE;
 1881         xs->error = XS_NOERROR;
 1882         xs->resid = xs->datalen;
 1883         xs->status = SCSI_OK;
 1884 
 1885 #ifdef SCSIPI_DEBUG
 1886         if (xs->xs_periph->periph_dbflags & SCSIPI_DB3) {
 1887                 printf("scsipi_execute_xs: ");
 1888                 show_scsipi_xs(xs);
 1889                 printf("\n");
 1890         }
 1891 #endif
 1892 
 1893         /*
 1894          * Deal with command tagging:
 1895          *
 1896          *      - If the device's current operating mode doesn't
 1897          *        include tagged queueing, clear the tag mask.
 1898          *
 1899          *      - If the device's current operating mode *does*
 1900          *        include tagged queueing, set the tag_type in
 1901          *        the xfer to the appropriate byte for the tag
 1902          *        message.
 1903          */
 1904         if ((PERIPH_XFER_MODE(periph) & PERIPH_CAP_TQING) == 0 ||
 1905                 (xs->xs_control & XS_CTL_REQSENSE)) {
 1906                 xs->xs_control &= ~XS_CTL_TAGMASK;
 1907                 xs->xs_tag_type = 0;
 1908         } else {
 1909                 /*
 1910                  * If the request doesn't specify a tag, give Head
 1911                  * tags to URGENT operations and Ordered tags to
 1912                  * everything else.
 1913                  */
 1914                 if (XS_CTL_TAGTYPE(xs) == 0) {
 1915                         if (xs->xs_control & XS_CTL_URGENT)
 1916                                 xs->xs_control |= XS_CTL_HEAD_TAG;
 1917                         else
 1918                                 xs->xs_control |= XS_CTL_ORDERED_TAG;
 1919                 }
 1920 
 1921                 switch (XS_CTL_TAGTYPE(xs)) {
 1922                 case XS_CTL_ORDERED_TAG:
 1923                         xs->xs_tag_type = MSG_ORDERED_Q_TAG;
 1924                         break;
 1925 
 1926                 case XS_CTL_SIMPLE_TAG:
 1927                         xs->xs_tag_type = MSG_SIMPLE_Q_TAG;
 1928                         break;
 1929 
 1930                 case XS_CTL_HEAD_TAG:
 1931                         xs->xs_tag_type = MSG_HEAD_OF_Q_TAG;
 1932                         break;
 1933 
 1934                 default:
 1935                         scsipi_printaddr(periph);
 1936                         printf("invalid tag mask 0x%08x\n",
 1937                             XS_CTL_TAGTYPE(xs));
 1938                         panic("scsipi_execute_xs");
 1939                 }
 1940         }
 1941 
 1942         /* If the adaptor wants us to poll, poll. */
 1943         if (chan->chan_adapter->adapt_flags & SCSIPI_ADAPT_POLL_ONLY)
 1944                 xs->xs_control |= XS_CTL_POLL;
 1945 
 1946         /*
 1947          * If we don't yet have a completion thread, or we are to poll for
 1948          * completion, clear the ASYNC flag.
 1949          */
 1950         oasync =  (xs->xs_control & XS_CTL_ASYNC);
 1951         if (chan->chan_thread == NULL || (xs->xs_control & XS_CTL_POLL) != 0)
 1952                 xs->xs_control &= ~XS_CTL_ASYNC;
 1953 
 1954         async = (xs->xs_control & XS_CTL_ASYNC);
 1955         poll = (xs->xs_control & XS_CTL_POLL);
 1956 
 1957 #ifdef DIAGNOSTIC
 1958         if (oasync != 0 && xs->bp == NULL)
 1959                 panic("scsipi_execute_xs: XS_CTL_ASYNC but no buf");
 1960 #endif
 1961 
 1962         /*
 1963          * Enqueue the transfer.  If we're not polling for completion, this
 1964          * should ALWAYS return `no error'.
 1965          */
 1966         error = scsipi_enqueue(xs);
 1967         if (error) {
 1968                 if (poll == 0) {
 1969                         scsipi_printaddr(periph);
 1970                         printf("not polling, but enqueue failed with %d\n",
 1971                             error);
 1972                         panic("scsipi_execute_xs");
 1973                 }
 1974 
 1975                 scsipi_printaddr(periph);
 1976                 printf("should have flushed queue?\n");
 1977                 goto free_xs;
 1978         }
 1979 
 1980  restarted:
 1981         scsipi_run_queue(chan);
 1982 
 1983         /*
 1984          * The xfer is enqueued, and possibly running.  If it's to be
 1985          * completed asynchronously, just return now.
 1986          */
 1987         if (async)
 1988                 return (0);
 1989 
 1990         /*
 1991          * Not an asynchronous command; wait for it to complete.
 1992          */
 1993         s = splbio();
 1994         while ((xs->xs_status & XS_STS_DONE) == 0) {
 1995                 if (poll) {
 1996                         scsipi_printaddr(periph);
 1997                         printf("polling command not done\n");
 1998                         panic("scsipi_execute_xs");
 1999                 }
 2000                 (void) tsleep(xs, PRIBIO, "xscmd", 0);
 2001         }
 2002         splx(s);
 2003 
 2004         /*
 2005          * Command is complete.  scsipi_done() has awakened us to perform
 2006          * the error handling.
 2007          */
 2008         error = scsipi_complete(xs);
 2009         if (error == ERESTART)
 2010                 goto restarted;
 2011 
 2012         /*
 2013          * If it was meant to run async and we cleared aync ourselve,
 2014          * don't return an error here. It has already been handled
 2015          */
 2016         if (oasync)
 2017                 error = 0;
 2018         /*
 2019          * Command completed successfully or fatal error occurred.  Fall
 2020          * into....
 2021          */
 2022  free_xs:
 2023         if (xs->xs_control & XS_CTL_DATA_ONSTACK)
 2024                 PRELE(curlwp);
 2025 
 2026         s = splbio();
 2027         scsipi_put_xs(xs);
 2028         splx(s);
 2029 
 2030         /*
 2031          * Kick the queue, keep it running in case it stopped for some
 2032          * reason.
 2033          */
 2034         scsipi_run_queue(chan);
 2035 
 2036         return (error);
 2037 }
 2038 
 2039 /*
 2040  * scsipi_completion_thread:
 2041  *
 2042  *      This is the completion thread.  We wait for errors on
 2043  *      asynchronous xfers, and perform the error handling
 2044  *      function, restarting the command, if necessary.
 2045  */
 2046 static void
 2047 scsipi_completion_thread(void *arg)
 2048 {
 2049         struct scsipi_channel *chan = arg;
 2050         struct scsipi_xfer *xs;
 2051         int s;
 2052 
 2053         if (chan->chan_init_cb)
 2054                 (*chan->chan_init_cb)(chan, chan->chan_init_cb_arg);
 2055 
 2056         s = splbio();
 2057         chan->chan_flags |= SCSIPI_CHAN_TACTIVE;
 2058         splx(s);
 2059         for (;;) {
 2060                 s = splbio();
 2061                 xs = TAILQ_FIRST(&chan->chan_complete);
 2062                 if (xs == NULL && chan->chan_tflags  == 0) {
 2063                         /* nothing to do; wait */
 2064                         (void) tsleep(&chan->chan_complete, PRIBIO,
 2065                             "sccomp", 0);
 2066                         splx(s);
 2067                         continue;
 2068                 }
 2069                 if (chan->chan_tflags & SCSIPI_CHANT_CALLBACK) {
 2070                         /* call chan_callback from thread context */
 2071                         chan->chan_tflags &= ~SCSIPI_CHANT_CALLBACK;
 2072                         chan->chan_callback(chan, chan->chan_callback_arg);
 2073                         splx(s);
 2074                         continue;
 2075                 }
 2076                 if (chan->chan_tflags & SCSIPI_CHANT_GROWRES) {
 2077                         /* attempt to get more openings for this channel */
 2078                         chan->chan_tflags &= ~SCSIPI_CHANT_GROWRES;
 2079                         scsipi_adapter_request(chan,
 2080                             ADAPTER_REQ_GROW_RESOURCES, NULL);
 2081                         scsipi_channel_thaw(chan, 1);
 2082                         splx(s);
 2083                         if (chan->chan_tflags & SCSIPI_CHANT_GROWRES) {
 2084                                 preempt(1);
 2085                         }
 2086                         continue;
 2087                 }
 2088                 if (chan->chan_tflags & SCSIPI_CHANT_KICK) {
 2089                         /* explicitly run the queues for this channel */
 2090                         chan->chan_tflags &= ~SCSIPI_CHANT_KICK;
 2091                         scsipi_run_queue(chan);
 2092                         splx(s);
 2093                         continue;
 2094                 }
 2095                 if (chan->chan_tflags & SCSIPI_CHANT_SHUTDOWN) {
 2096                         splx(s);
 2097                         break;
 2098                 }
 2099                 if (xs) {
 2100                         TAILQ_REMOVE(&chan->chan_complete, xs, channel_q);
 2101                         splx(s);
 2102 
 2103                         /*
 2104                          * Have an xfer with an error; process it.
 2105                          */
 2106                         (void) scsipi_complete(xs);
 2107 
 2108                         /*
 2109                          * Kick the queue; keep it running if it was stopped
 2110                          * for some reason.
 2111                          */
 2112                         scsipi_run_queue(chan);
 2113                 } else {
 2114                         splx(s);
 2115                 }
 2116         }
 2117 
 2118         chan->chan_thread = NULL;
 2119 
 2120         /* In case parent is waiting for us to exit. */
 2121         wakeup(&chan->chan_thread);
 2122 
 2123         kthread_exit(0);
 2124 }
 2125 
 2126 /*
 2127  * scsipi_create_completion_thread:
 2128  *
 2129  *      Callback to actually create the completion thread.
 2130  */
 2131 void
 2132 scsipi_create_completion_thread(void *arg)
 2133 {
 2134         struct scsipi_channel *chan = arg;
 2135         struct scsipi_adapter *adapt = chan->chan_adapter;
 2136 
 2137         if (kthread_create1(scsipi_completion_thread, chan,
 2138             &chan->chan_thread, "%s", chan->chan_name)) {
 2139                 printf("%s: unable to create completion thread for "
 2140                     "channel %d\n", adapt->adapt_dev->dv_xname,
 2141                     chan->chan_channel);
 2142                 panic("scsipi_create_completion_thread");
 2143         }
 2144 }
 2145 
 2146 /*
 2147  * scsipi_thread_call_callback:
 2148  *
 2149  *      request to call a callback from the completion thread
 2150  */
 2151 int
 2152 scsipi_thread_call_callback(struct scsipi_channel *chan,
 2153     void (*callback)(struct scsipi_channel *, void *), void *arg)
 2154 {
 2155         int s;
 2156 
 2157         s = splbio();
 2158         if ((chan->chan_flags & SCSIPI_CHAN_TACTIVE) == 0) {
 2159                 /* kernel thread doesn't exist yet */
 2160                 splx(s);
 2161                 return ESRCH;
 2162         }
 2163         if (chan->chan_tflags & SCSIPI_CHANT_CALLBACK) {
 2164                 splx(s);
 2165                 return EBUSY;
 2166         }
 2167         scsipi_channel_freeze(chan, 1);
 2168         chan->chan_callback = callback;
 2169         chan->chan_callback_arg = arg;
 2170         chan->chan_tflags |= SCSIPI_CHANT_CALLBACK;
 2171         wakeup(&chan->chan_complete);
 2172         splx(s);
 2173         return(0);
 2174 }
 2175 
 2176 /*
 2177  * scsipi_async_event:
 2178  *
 2179  *      Handle an asynchronous event from an adapter.
 2180  */
 2181 void
 2182 scsipi_async_event(struct scsipi_channel *chan, scsipi_async_event_t event,
 2183     void *arg)
 2184 {
 2185         int s;
 2186 
 2187         s = splbio();
 2188         switch (event) {
 2189         case ASYNC_EVENT_MAX_OPENINGS:
 2190                 scsipi_async_event_max_openings(chan,
 2191                     (struct scsipi_max_openings *)arg);
 2192                 break;
 2193 
 2194         case ASYNC_EVENT_XFER_MODE:
 2195                 scsipi_async_event_xfer_mode(chan,
 2196                     (struct scsipi_xfer_mode *)arg);
 2197                 break;
 2198         case ASYNC_EVENT_RESET:
 2199                 scsipi_async_event_channel_reset(chan);
 2200                 break;
 2201         }
 2202         splx(s);
 2203 }
 2204 
 2205 /*
 2206  * scsipi_print_xfer_mode:
 2207  *
 2208  *      Print a periph's capabilities.
 2209  */
 2210 void
 2211 scsipi_print_xfer_mode(struct scsipi_periph *periph)
 2212 {
 2213         int period, freq, speed, mbs;
 2214 
 2215         if ((periph->periph_flags & PERIPH_MODE_VALID) == 0)
 2216                 return;
 2217 
 2218         aprint_normal("%s: ", periph->periph_dev->dv_xname);
 2219         if (periph->periph_mode & (PERIPH_CAP_SYNC | PERIPH_CAP_DT)) {
 2220                 period = scsipi_sync_factor_to_period(periph->periph_period);
 2221                 aprint_normal("sync (%d.%02dns offset %d)",
 2222                     period / 100, period % 100, periph->periph_offset);
 2223         } else
 2224                 aprint_normal("async");
 2225 
 2226         if (periph->periph_mode & PERIPH_CAP_WIDE32)
 2227                 aprint_normal(", 32-bit");
 2228         else if (periph->periph_mode & (PERIPH_CAP_WIDE16 | PERIPH_CAP_DT))
 2229                 aprint_normal(", 16-bit");
 2230         else
 2231                 aprint_normal(", 8-bit");
 2232 
 2233         if (periph->periph_mode & (PERIPH_CAP_SYNC | PERIPH_CAP_DT)) {
 2234                 freq = scsipi_sync_factor_to_freq(periph->periph_period);
 2235                 speed = freq;
 2236                 if (periph->periph_mode & PERIPH_CAP_WIDE32)
 2237                         speed *= 4;
 2238                 else if (periph->periph_mode &
 2239                     (PERIPH_CAP_WIDE16 | PERIPH_CAP_DT))
 2240                         speed *= 2;
 2241                 mbs = speed / 1000;
 2242                 if (mbs > 0)
 2243                         aprint_normal(" (%d.%03dMB/s)", mbs, speed % 1000);
 2244                 else
 2245                         aprint_normal(" (%dKB/s)", speed % 1000);
 2246         }
 2247 
 2248         aprint_normal(" transfers");
 2249 
 2250         if (periph->periph_mode & PERIPH_CAP_TQING)
 2251                 aprint_normal(", tagged queueing");
 2252 
 2253         aprint_normal("\n");
 2254 }
 2255 
 2256 /*
 2257  * scsipi_async_event_max_openings:
 2258  *
 2259  *      Update the maximum number of outstanding commands a
 2260  *      device may have.
 2261  */
 2262 static void
 2263 scsipi_async_event_max_openings(struct scsipi_channel *chan,
 2264     struct scsipi_max_openings *mo)
 2265 {
 2266         struct scsipi_periph *periph;
 2267         int minlun, maxlun;
 2268 
 2269         if (mo->mo_lun == -1) {
 2270                 /*
 2271                  * Wildcarded; apply it to all LUNs.
 2272                  */
 2273                 minlun = 0;
 2274                 maxlun = chan->chan_nluns - 1;
 2275         } else
 2276                 minlun = maxlun = mo->mo_lun;
 2277 
 2278         /* XXX This could really suck with a large LUN space. */
 2279         for (; minlun <= maxlun; minlun++) {
 2280                 periph = scsipi_lookup_periph(chan, mo->mo_target, minlun);
 2281                 if (periph == NULL)
 2282                         continue;
 2283 
 2284                 if (mo->mo_openings < periph->periph_openings)
 2285                         periph->periph_openings = mo->mo_openings;
 2286                 else if (mo->mo_openings > periph->periph_openings &&
 2287                     (periph->periph_flags & PERIPH_GROW_OPENINGS) != 0)
 2288                         periph->periph_openings = mo->mo_openings;
 2289         }
 2290 }
 2291 
 2292 /*
 2293  * scsipi_async_event_xfer_mode:
 2294  *
 2295  *      Update the xfer mode for all periphs sharing the
 2296  *      specified I_T Nexus.
 2297  */
 2298 static void
 2299 scsipi_async_event_xfer_mode(struct scsipi_channel *chan,
 2300     struct scsipi_xfer_mode *xm)
 2301 {
 2302         struct scsipi_periph *periph;
 2303         int lun, announce, mode, period, offset;
 2304 
 2305         for (lun = 0; lun < chan->chan_nluns; lun++) {
 2306                 periph = scsipi_lookup_periph(chan, xm->xm_target, lun);
 2307                 if (periph == NULL)
 2308                         continue;
 2309                 announce = 0;
 2310 
 2311                 /*
 2312                  * Clamp the xfer mode down to this periph's capabilities.
 2313                  */
 2314                 mode = xm->xm_mode & periph->periph_cap;
 2315                 if (mode & PERIPH_CAP_SYNC) {
 2316                         period = xm->xm_period;
 2317                         offset = xm->xm_offset;
 2318                 } else {
 2319                         period = 0;
 2320                         offset = 0;
 2321                 }
 2322 
 2323                 /*
 2324                  * If we do not have a valid xfer mode yet, or the parameters
 2325                  * are different, announce them.
 2326                  */
 2327                 if ((periph->periph_flags & PERIPH_MODE_VALID) == 0 ||
 2328                     periph->periph_mode != mode ||
 2329                     periph->periph_period != period ||
 2330                     periph->periph_offset != offset)
 2331                         announce = 1;
 2332 
 2333                 periph->periph_mode = mode;
 2334                 periph->periph_period = period;
 2335                 periph->periph_offset = offset;
 2336                 periph->periph_flags |= PERIPH_MODE_VALID;
 2337 
 2338                 if (announce)
 2339                         scsipi_print_xfer_mode(periph);
 2340         }
 2341 }
 2342 
 2343 /*
 2344  * scsipi_set_xfer_mode:
 2345  *
 2346  *      Set the xfer mode for the specified I_T Nexus.
 2347  */
 2348 void
 2349 scsipi_set_xfer_mode(struct scsipi_channel *chan, int target, int immed)
 2350 {
 2351         struct scsipi_xfer_mode xm;
 2352         struct scsipi_periph *itperiph;
 2353         int lun, s;
 2354 
 2355         /*
 2356          * Go to the minimal xfer mode.
 2357          */
 2358         xm.xm_target = target;
 2359         xm.xm_mode = 0;
 2360         xm.xm_period = 0;                       /* ignored */
 2361         xm.xm_offset = 0;                       /* ignored */
 2362 
 2363         /*
 2364          * Find the first LUN we know about on this I_T Nexus.
 2365          */
 2366         for (itperiph = NULL, lun = 0; lun < chan->chan_nluns; lun++) {
 2367                 itperiph = scsipi_lookup_periph(chan, target, lun);
 2368                 if (itperiph != NULL)
 2369                         break;
 2370         }
 2371         if (itperiph != NULL) {
 2372                 xm.xm_mode = itperiph->periph_cap;
 2373                 /*
 2374                  * Now issue the request to the adapter.
 2375                  */
 2376                 s = splbio();
 2377                 scsipi_adapter_request(chan, ADAPTER_REQ_SET_XFER_MODE, &xm);
 2378                 splx(s);
 2379                 /*
 2380                  * If we want this to happen immediately, issue a dummy
 2381                  * command, since most adapters can't really negotiate unless
 2382                  * they're executing a job.
 2383                  */
 2384                 if (immed != 0) {
 2385                         (void) scsipi_test_unit_ready(itperiph,
 2386                             XS_CTL_DISCOVERY | XS_CTL_IGNORE_ILLEGAL_REQUEST |
 2387                             XS_CTL_IGNORE_NOT_READY |
 2388                             XS_CTL_IGNORE_MEDIA_CHANGE);
 2389                 }
 2390         }
 2391 }
 2392 
 2393 /*
 2394  * scsipi_channel_reset:
 2395  *
 2396  *      handle scsi bus reset
 2397  * called at splbio
 2398  */
 2399 static void
 2400 scsipi_async_event_channel_reset(struct scsipi_channel *chan)
 2401 {
 2402         struct scsipi_xfer *xs, *xs_next;
 2403         struct scsipi_periph *periph;
 2404         int target, lun;
 2405 
 2406         /*
 2407          * Channel has been reset. Also mark as reset pending REQUEST_SENSE
 2408          * commands; as the sense is not available any more.
 2409          * can't call scsipi_done() from here, as the command has not been
 2410          * sent to the adapter yet (this would corrupt accounting).
 2411          */
 2412 
 2413         for (xs = TAILQ_FIRST(&chan->chan_queue); xs != NULL; xs = xs_next) {
 2414                 xs_next = TAILQ_NEXT(xs, channel_q);
 2415                 if (xs->xs_control & XS_CTL_REQSENSE) {
 2416                         TAILQ_REMOVE(&chan->chan_queue, xs, channel_q);
 2417                         xs->error = XS_RESET;
 2418                         if ((xs->xs_control & XS_CTL_ASYNC) != 0)
 2419                                 TAILQ_INSERT_TAIL(&chan->chan_complete, xs,
 2420                                     channel_q);
 2421                 }
 2422         }
 2423         wakeup(&chan->chan_complete);
 2424         /* Catch xs with pending sense which may not have a REQSENSE xs yet */
 2425         for (target = 0; target < chan->chan_ntargets; target++) {
 2426                 if (target == chan->chan_id)
 2427                         continue;
 2428                 for (lun = 0; lun <  chan->chan_nluns; lun++) {
 2429                         periph = scsipi_lookup_periph(chan, target, lun);
 2430                         if (periph) {
 2431                                 xs = periph->periph_xscheck;
 2432                                 if (xs)
 2433                                         xs->error = XS_RESET;
 2434                         }
 2435                 }
 2436         }
 2437 }
 2438 
 2439 /*
 2440  * scsipi_target_detach:
 2441  *
 2442  *      detach all periph associated with a I_T
 2443  *      must be called from valid thread context
 2444  */
 2445 int
 2446 scsipi_target_detach(struct scsipi_channel *chan, int target, int lun,
 2447     int flags)
 2448 {
 2449         struct scsipi_periph *periph;
 2450         int ctarget, mintarget, maxtarget;
 2451         int clun, minlun, maxlun;
 2452         int error;
 2453 
 2454         if (target == -1) {
 2455                 mintarget = 0;
 2456                 maxtarget = chan->chan_ntargets;
 2457         } else {
 2458                 if (target == chan->chan_id)
 2459                         return EINVAL;
 2460                 if (target < 0 || target >= chan->chan_ntargets)
 2461                         return EINVAL;
 2462                 mintarget = target;
 2463                 maxtarget = target + 1;
 2464         }
 2465 
 2466         if (lun == -1) {
 2467                 minlun = 0;
 2468                 maxlun = chan->chan_nluns;
 2469         } else {
 2470                 if (lun < 0 || lun >= chan->chan_nluns)
 2471                         return EINVAL;
 2472                 minlun = lun;
 2473                 maxlun = lun + 1;
 2474         }
 2475 
 2476         for (ctarget = mintarget; ctarget < maxtarget; ctarget++) {
 2477                 if (ctarget == chan->chan_id)
 2478                         continue;
 2479 
 2480                 for (clun = minlun; clun < maxlun; clun++) {
 2481                         periph = scsipi_lookup_periph(chan, ctarget, clun);
 2482                         if (periph == NULL)
 2483                                 continue;
 2484                         error = config_detach(periph->periph_dev, flags);
 2485                         if (error)
 2486                                 return (error);
 2487                 }
 2488         }
 2489         return(0);
 2490 }
 2491 
 2492 /*
 2493  * scsipi_adapter_addref:
 2494  *
 2495  *      Add a reference to the adapter pointed to by the provided
 2496  *      link, enabling the adapter if necessary.
 2497  */
 2498 int
 2499 scsipi_adapter_addref(struct scsipi_adapter *adapt)
 2500 {
 2501         int s, error = 0;
 2502 
 2503         s = splbio();
 2504         if (adapt->adapt_refcnt++ == 0 && adapt->adapt_enable != NULL) {
 2505                 error = (*adapt->adapt_enable)(adapt->adapt_dev, 1);
 2506                 if (error)
 2507                         adapt->adapt_refcnt--;
 2508         }
 2509         splx(s);
 2510         return (error);
 2511 }
 2512 
 2513 /*
 2514  * scsipi_adapter_delref:
 2515  *
 2516  *      Delete a reference to the adapter pointed to by the provided
 2517  *      link, disabling the adapter if possible.
 2518  */
 2519 void
 2520 scsipi_adapter_delref(struct scsipi_adapter *adapt)
 2521 {
 2522         int s;
 2523 
 2524         s = splbio();
 2525         if (adapt->adapt_refcnt-- == 1 && adapt->adapt_enable != NULL)
 2526                 (void) (*adapt->adapt_enable)(adapt->adapt_dev, 0);
 2527         splx(s);
 2528 }
 2529 
 2530 static struct scsipi_syncparam {
 2531         int     ss_factor;
 2532         int     ss_period;      /* ns * 100 */
 2533 } scsipi_syncparams[] = {
 2534         { 0x08,          625 }, /* FAST-160 (Ultra320) */
 2535         { 0x09,         1250 }, /* FAST-80 (Ultra160) */
 2536         { 0x0a,         2500 }, /* FAST-40 40MHz (Ultra2) */
 2537         { 0x0b,         3030 }, /* FAST-40 33MHz (Ultra2) */
 2538         { 0x0c,         5000 }, /* FAST-20 (Ultra) */
 2539 };
 2540 static const int scsipi_nsyncparams =
 2541     sizeof(scsipi_syncparams) / sizeof(scsipi_syncparams[0]);
 2542 
 2543 int
 2544 scsipi_sync_period_to_factor(int period /* ns * 100 */)
 2545 {
 2546         int i;
 2547 
 2548         for (i = 0; i < scsipi_nsyncparams; i++) {
 2549                 if (period <= scsipi_syncparams[i].ss_period)
 2550                         return (scsipi_syncparams[i].ss_factor);
 2551         }
 2552 
 2553         return ((period / 100) / 4);
 2554 }
 2555 
 2556 int
 2557 scsipi_sync_factor_to_period(int factor)
 2558 {
 2559         int i;
 2560 
 2561         for (i = 0; i < scsipi_nsyncparams; i++) {
 2562                 if (factor == scsipi_syncparams[i].ss_factor)
 2563                         return (scsipi_syncparams[i].ss_period);
 2564         }
 2565 
 2566         return ((factor * 4) * 100);
 2567 }
 2568 
 2569 int
 2570 scsipi_sync_factor_to_freq(int factor)
 2571 {
 2572         int i;
 2573 
 2574         for (i = 0; i < scsipi_nsyncparams; i++) {
 2575                 if (factor == scsipi_syncparams[i].ss_factor)
 2576                         return (100000000 / scsipi_syncparams[i].ss_period);
 2577         }
 2578 
 2579         return (10000000 / ((factor * 4) * 10));
 2580 }
 2581 
 2582 #ifdef SCSIPI_DEBUG
 2583 /*
 2584  * Given a scsipi_xfer, dump the request, in all it's glory
 2585  */
 2586 void
 2587 show_scsipi_xs(struct scsipi_xfer *xs)
 2588 {
 2589 
 2590         printf("xs(%p): ", xs);
 2591         printf("xs_control(0x%08x)", xs->xs_control);
 2592         printf("xs_status(0x%08x)", xs->xs_status);
 2593         printf("periph(%p)", xs->xs_periph);
 2594         printf("retr(0x%x)", xs->xs_retries);
 2595         printf("timo(0x%x)", xs->timeout);
 2596         printf("cmd(%p)", xs->cmd);
 2597         printf("len(0x%x)", xs->cmdlen);
 2598         printf("data(%p)", xs->data);
 2599         printf("len(0x%x)", xs->datalen);
 2600         printf("res(0x%x)", xs->resid);
 2601         printf("err(0x%x)", xs->error);
 2602         printf("bp(%p)", xs->bp);
 2603         show_scsipi_cmd(xs);
 2604 }
 2605 
 2606 void
 2607 show_scsipi_cmd(struct scsipi_xfer *xs)
 2608 {
 2609         u_char *b = (u_char *) xs->cmd;
 2610         int i = 0;
 2611 
 2612         scsipi_printaddr(xs->xs_periph);
 2613         printf(" command: ");
 2614 
 2615         if ((xs->xs_control & XS_CTL_RESET) == 0) {
 2616                 while (i < xs->cmdlen) {
 2617                         if (i)
 2618                                 printf(",");
 2619                         printf("0x%x", b[i++]);
 2620                 }
 2621                 printf("-[%d bytes]\n", xs->datalen);
 2622                 if (xs->datalen)
 2623                         show_mem(xs->data, min(64, xs->datalen));
 2624         } else
 2625                 printf("-RESET-\n");
 2626 }
 2627 
 2628 void
 2629 show_mem(u_char *address, int num)
 2630 {
 2631         int x;
 2632 
 2633         printf("------------------------------");
 2634         for (x = 0; x < num; x++) {
 2635                 if ((x % 16) == 0)
 2636                         printf("\n%03d: ", x);
 2637                 printf("%02x ", *address++);
 2638         }
 2639         printf("\n------------------------------\n");
 2640 }
 2641 #endif /* SCSIPI_DEBUG */

Cache object: acb41558e0b0dc1d073b546d5242b3a8


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