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/scsi/scsi_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 /*
    2  * Written By Julian ELischer
    3  * Copyright julian Elischer 1993.
    4  * Permission is granted to use or redistribute this file in any way as long
    5  * as this notice remains. Julian Elischer does not guarantee that this file
    6  * is totally correct for any given task and users of this file must
    7  * accept responsibility for any damage that occurs from the application of this
    8  * file.
    9  *
   10  * Written by Julian Elischer (julian@dialix.oz.au)
   11  * $FreeBSD: src/sys/scsi/scsi_base.c,v 1.39.4.8 1999/09/05 08:21:38 peter Exp $
   12  */
   13 
   14 #include "opt_bounce.h"
   15 #include "opt_scsi.h"
   16 
   17 #define SPLSD splbio
   18 #define ESUCCESS 0
   19 #include <sys/types.h>
   20 #include <sys/param.h>
   21 #include <sys/systm.h>
   22 #include <sys/proc.h>
   23 #include <sys/kernel.h>
   24 #include <sys/buf.h>
   25 #include <sys/uio.h>
   26 #include <sys/malloc.h>
   27 #include <sys/errno.h>
   28 
   29 #include <machine/clock.h>
   30 
   31 #include <vm/vm.h>
   32 #include <vm/vm_param.h>
   33 #include <vm/pmap.h>
   34 
   35 #include <scsi/scsi_all.h>
   36 #include <scsi/scsi_disk.h>
   37 #include <scsi/scsiconf.h>
   38 
   39 static errval sc_err1(struct scsi_xfer *);
   40 static errval scsi_interpret_sense(struct scsi_xfer *);
   41 static struct scsi_xfer *get_xs( struct scsi_link *sc_link, u_int32_t flags);
   42 static void free_xs(struct scsi_xfer *xs, struct scsi_link *sc_link,
   43                 u_int32_t flags);
   44 static void show_mem(unsigned char *address, u_int32_t num);
   45 static void show_scsi_xs (struct scsi_xfer *);
   46 
   47 #ifdef notyet
   48 static int scsi_sense_qualifiers (struct scsi_xfer *, int *, int *);
   49 #endif
   50 
   51 static struct scsi_xfer *next_free_xs;
   52 
   53 /*
   54  * Get a scsi transfer structure for the caller. Charge the structure
   55  * to the device that is referenced by the sc_link structure. If the
   56  * sc_link structure has no 'credits' then the device already has the
   57  * maximum number or outstanding operations under way. In this stage,
   58  * wait on the structure so that when one is freed, we are awoken again
   59  * If the SCSI_NOSLEEP flag is set, then do not wait, but rather, return
   60  * a NULL pointer, signifying that no slots were available
   61  * Note in the link structure, that we are waiting on it.
   62  */
   63 
   64 static struct scsi_xfer *
   65 get_xs(sc_link, flags)
   66         struct  scsi_link *sc_link;     /* who to charge the xs to */
   67         u_int32_t       flags;                  /* if this call can sleep */
   68 {
   69         struct  scsi_xfer *xs;
   70         u_int32_t       s;
   71 
   72         SC_DEBUG(sc_link, SDEV_DB3, ("get_xs\n"));
   73         s = splbio();
   74         while (!sc_link->opennings) {
   75                 SC_DEBUG(sc_link, SDEV_DB3, ("sleeping\n"));
   76                 if (flags & SCSI_NOSLEEP) {
   77                         splx(s);
   78                         return 0;
   79                 }
   80                 sc_link->flags |= SDEV_WAITING;
   81                 tsleep((caddr_t)sc_link, PRIBIO, "scsiget", 0);
   82         }
   83         sc_link->active++;
   84         sc_link->opennings--;
   85         if ( (xs = next_free_xs) ) {
   86                 next_free_xs = xs->next;
   87                 splx(s);
   88         } else {
   89                 splx(s);
   90                 SC_DEBUG(sc_link, SDEV_DB3, ("making\n"));
   91                 xs = malloc(sizeof(*xs), M_TEMP,
   92                     ((flags & SCSI_NOSLEEP) ? M_NOWAIT : M_WAITOK));
   93                 if (xs == NULL) {
   94                         sc_print_addr(sc_link);
   95                         printf("cannot allocate scsi xs\n");
   96                         return (NULL);
   97                 }
   98         }
   99         SC_DEBUG(sc_link, SDEV_DB3, ("returning\n"));
  100         xs->sc_link = sc_link;
  101         return (xs);
  102 }
  103 
  104 /*
  105  * Given a scsi_xfer struct, and a device (referenced through sc_link)
  106  * return the struct to the free pool and credit the device with it
  107  * If another process is waiting for an xs, do a wakeup, let it proceed
  108  */
  109 static void
  110 free_xs(xs, sc_link, flags)
  111         struct scsi_xfer *xs;
  112         struct scsi_link *sc_link;      /* who to credit for returning it */
  113         u_int32_t flags;
  114 {
  115         xs->next = next_free_xs;
  116         next_free_xs = xs;
  117 
  118         SC_DEBUG(sc_link, SDEV_DB3, ("free_xs\n"));
  119         /* if was 0 and someone waits, wake them up */
  120         sc_link->active--;
  121         if ((!sc_link->opennings++) && (sc_link->flags & SDEV_WAITING)) {
  122                 sc_link->flags &= ~SDEV_WAITING;
  123                 wakeup((caddr_t)sc_link); /* remember, it wakes them ALL up */
  124         } else {
  125                 if (sc_link->device->start) {
  126                         SC_DEBUG(sc_link, SDEV_DB2, ("calling private start()\n"));
  127                         (*(sc_link->device->start)) (sc_link->dev_unit, flags);
  128                 }
  129         }
  130 }
  131 
  132 /* XXX dufault: Replace "sd_size" with "scsi_read_capacity"
  133  * when bde is done with sd.c
  134  */
  135 /*
  136  * Find out from the device what its capacity is.
  137  */
  138 u_int32_t
  139 scsi_read_capacity(sc_link, blk_size, flags)
  140         struct scsi_link *sc_link;
  141         u_int32_t *blk_size;
  142         u_int32_t flags;
  143 {
  144         struct scsi_read_cap_data rdcap;
  145         struct scsi_read_capacity scsi_cmd;
  146         u_int32_t size;
  147 
  148         /*
  149          * make up a scsi command and ask the scsi driver to do
  150          * it for you.
  151          */
  152         bzero(&scsi_cmd, sizeof(scsi_cmd));
  153         scsi_cmd.op_code = READ_CAPACITY;
  154 
  155         /*
  156          * If the command works, interpret the result as a 4 byte
  157          * number of blocks
  158          */
  159         if (scsi_scsi_cmd(sc_link,
  160                 (struct scsi_generic *) &scsi_cmd,
  161                 sizeof(scsi_cmd),
  162                 (u_char *) & rdcap,
  163                 sizeof(rdcap),
  164                 4,
  165                 5000000,        /* WORMs tend to take a HUGE amount of time */
  166                 NULL,
  167                 flags | SCSI_DATA_IN) != 0) {
  168 
  169                 sc_print_addr(sc_link);
  170                 printf("could not get size\n");
  171                 return (0);
  172         } else {
  173                 size = scsi_4btou(&rdcap.addr_3) + 1;
  174                 if (blk_size)
  175                         *blk_size = scsi_4btou(&rdcap.length_3);
  176         }
  177         return (size);
  178 }
  179 
  180 errval
  181 scsi_reset_target(sc_link)
  182         struct scsi_link *sc_link;
  183 {
  184         return (scsi_scsi_cmd(sc_link,
  185                 0,
  186                 0,
  187                 0,
  188                 0,
  189                 1,
  190                 2000,
  191                 NULL,
  192                 SCSI_RESET));
  193 }
  194 
  195 errval
  196 scsi_target_mode(sc_link, on_off)
  197         struct scsi_link *sc_link;
  198         int on_off;
  199 {
  200         struct scsi_generic scsi_cmd;
  201         bzero(&scsi_cmd, sizeof(scsi_cmd));
  202         scsi_cmd.opcode = SCSI_OP_TARGET;
  203         scsi_cmd.bytes[0] = (on_off) ? 1 : 0;
  204 
  205         return (scsi_scsi_cmd(sc_link,
  206                 &scsi_cmd,
  207                 sizeof(scsi_cmd),
  208                 0,
  209                 0,
  210                 1,
  211                 2000,
  212                 NULL,
  213                 SCSI_ESCAPE));
  214 }
  215 
  216 /*
  217  * Get scsi driver to send a "are you ready?" command
  218  */
  219 errval
  220 scsi_test_unit_ready(sc_link, flags)
  221         struct scsi_link *sc_link;
  222         u_int32_t flags;
  223 {
  224         struct scsi_test_unit_ready scsi_cmd;
  225 
  226         bzero(&scsi_cmd, sizeof(scsi_cmd));
  227         scsi_cmd.op_code = TEST_UNIT_READY;
  228 
  229         return (scsi_scsi_cmd(sc_link,
  230                 (struct scsi_generic *) &scsi_cmd,
  231                 sizeof(scsi_cmd),
  232                 0,
  233                 0,
  234                 2,
  235                 100000,
  236                 NULL,
  237                 flags));
  238 }
  239 
  240 #ifdef SCSI_2_DEF
  241 /*
  242  * Do a scsi operation, asking a device to run as SCSI-II if it can.
  243  */
  244 errval
  245 scsi_change_def(sc_link, flags)
  246         struct scsi_link *sc_link;
  247         u_int32_t flags;
  248 {
  249         struct scsi_changedef scsi_cmd;
  250 
  251         bzero(&scsi_cmd, sizeof(scsi_cmd));
  252         scsi_cmd.op_code = CHANGE_DEFINITION;
  253         scsi_cmd.how = SC_SCSI_2;
  254 
  255         return (scsi_scsi_cmd(sc_link,
  256                 (struct scsi_generic *) &scsi_cmd,
  257                 sizeof(scsi_cmd),
  258                 0,
  259                 0,
  260                 2,
  261                 100000,
  262                 NULL,
  263                 flags));
  264 }
  265 #endif /* SCSI_2_DEF */
  266 
  267 /*
  268  * Do a scsi operation asking a device what it is
  269  * Use the scsi_cmd routine in the switch table.
  270  */
  271 errval
  272 scsi_inquire(sc_link, inqbuf, flags)
  273         struct scsi_link *sc_link;
  274         struct scsi_inquiry_data *inqbuf;
  275         u_int32_t flags;
  276 {
  277         struct scsi_inquiry scsi_cmd;
  278 
  279         bzero(&scsi_cmd, sizeof(scsi_cmd));
  280         scsi_cmd.op_code = INQUIRY;
  281         scsi_cmd.length = sizeof(struct scsi_inquiry_data);
  282 
  283         return (scsi_scsi_cmd(sc_link,
  284                 (struct scsi_generic *) &scsi_cmd,
  285                 sizeof(scsi_cmd),
  286                 (u_char *) inqbuf,
  287                 sizeof(struct scsi_inquiry_data),
  288                 2,
  289                 100000,
  290                 NULL,
  291                 SCSI_DATA_IN | flags));
  292 }
  293 
  294 /*
  295  * Prevent or allow the user to remove the media
  296  */
  297 errval
  298 scsi_prevent(sc_link, type, flags)
  299         struct scsi_link *sc_link;
  300         u_int32_t type, flags;
  301 {
  302         struct scsi_prevent scsi_cmd;
  303 
  304         bzero(&scsi_cmd, sizeof(scsi_cmd));
  305         scsi_cmd.op_code = PREVENT_ALLOW;
  306         scsi_cmd.how = type;
  307         return (scsi_scsi_cmd(sc_link,
  308                 (struct scsi_generic *) &scsi_cmd,
  309                 sizeof(scsi_cmd),
  310                 0,
  311                 0,
  312                 2,
  313                 100000,
  314                 NULL,
  315                 flags));
  316 }
  317 
  318 /*
  319  * Get scsi driver to send a "start up" command
  320  */
  321 errval
  322 scsi_start_unit(sc_link, flags)
  323         struct scsi_link *sc_link;
  324         u_int32_t flags;
  325 {
  326         struct scsi_start_stop scsi_cmd;
  327 
  328         bzero(&scsi_cmd, sizeof(scsi_cmd));
  329         scsi_cmd.op_code = START_STOP;
  330         scsi_cmd.how = SSS_START;
  331 
  332         return (scsi_scsi_cmd(sc_link,
  333                 (struct scsi_generic *) &scsi_cmd,
  334                 sizeof(scsi_cmd),
  335                 0,
  336                 0,
  337                 2,
  338                 30000,
  339                 NULL,
  340                 flags));
  341 }
  342 
  343 /*
  344  * Get scsi driver to send a "stop" command
  345  */
  346 errval
  347 scsi_stop_unit(sc_link, eject, flags)
  348         struct scsi_link *sc_link;
  349         u_int32_t eject;
  350         u_int32_t flags;
  351 {
  352         struct scsi_start_stop scsi_cmd;
  353 
  354         bzero(&scsi_cmd, sizeof(scsi_cmd));
  355         scsi_cmd.op_code = START_STOP;
  356         if (eject) {
  357                 scsi_cmd.how = SSS_LOEJ;
  358         }
  359 
  360         return (scsi_scsi_cmd(sc_link,
  361                 (struct scsi_generic *) &scsi_cmd,
  362                 sizeof(scsi_cmd),
  363                 0,
  364                 0,
  365                 2,
  366                 10000,
  367                 NULL,
  368                 flags));
  369 }
  370 
  371 /*
  372  * This routine is called by the scsi interrupt when the transfer is complete.
  373  */
  374 void
  375 scsi_done(xs)
  376         struct scsi_xfer *xs;
  377 {
  378         struct scsi_link *sc_link = xs->sc_link;
  379         struct buf *bp = xs->bp;
  380         errval  retval;
  381 
  382         SC_DEBUG(sc_link, SDEV_DB2, ("scsi_done\n"));
  383 #ifdef  SCSIDEBUG
  384         if (sc_link->flags & SDEV_DB1)
  385         {
  386                 show_scsi_cmd(xs);
  387         }
  388 #endif /*SCSIDEBUG */
  389         /*
  390          * If it's a user level request, bypass all usual completion processing,
  391          * let the user work it out.. We take reponsibility for freeing the
  392          * xs when the user returns. (and restarting the device's queue).
  393          */
  394         if (xs->flags & SCSI_USER) {
  395                 SC_DEBUG(sc_link, SDEV_DB3, ("calling user done()\n"));
  396                 scsi_user_done(xs); /* to take a copy of the sense etc. */
  397                 SC_DEBUG(sc_link, SDEV_DB3, ("returned from user done()\n "));
  398 
  399                 free_xs(xs, sc_link, SCSI_NOSLEEP); /* restarts queue too */
  400                 SC_DEBUG(sc_link, SDEV_DB3, ("returning to adapter\n"));
  401                 return;
  402         }
  403         /*
  404          * If the device has it's own done routine, call it first.
  405          * If it returns a legit error value, return that, otherwise
  406          * it wants us to continue with normal processing.
  407          */
  408 
  409         if (sc_link->device->done) {
  410                 SC_DEBUG(sc_link, SDEV_DB2, ("calling private done()\n"));
  411                 retval = (*sc_link->device->done) (xs);
  412                 if (retval == -1) {
  413                         free_xs(xs, sc_link, SCSI_NOSLEEP);     /*XXX */
  414                         return; /* it did it all, finish up */
  415                 }
  416                 /* XXX: This isn't used anywhere. Do you have plans for it,
  417                  * Julian? (dufault@hda.com).
  418                  * This allows a private 'done' handler to
  419                  * resubmit the command if it wants to retry,
  420                  * In this case the xs must NOT be freed. (julian)
  421                  */
  422                 if (retval == -2) {
  423                         return; /* it did it all, finish up */
  424                 }
  425                 SC_DEBUG(sc_link, SDEV_DB3, ("continuing with generic done()\n"));
  426         }
  427         if ((bp = xs->bp) == NULL) {
  428                 /*
  429                  * if it's a normal upper level request, then ask
  430                  * the upper level code to handle error checking
  431                  * rather than doing it here at interrupt time
  432                  */
  433                 wakeup((caddr_t)xs);
  434                 return;
  435         }
  436         /*
  437          * Go and handle errors now.
  438          * If it returns SCSIRET_DO_RETRY then we should RETRY
  439          */
  440         if ((retval = sc_err1(xs)) == SCSIRET_DO_RETRY) {
  441                 if ((*(sc_link->adapter->scsi_cmd)) (xs)
  442                     == SUCCESSFULLY_QUEUED) {   /* don't wake the job, ok? */
  443                         return;
  444                 }
  445                 xs->flags |= ITSDONE;
  446         }
  447 
  448         free_xs(xs, sc_link, SCSI_NOSLEEP); /* does a start if needed */
  449         biodone(bp);
  450 }
  451 
  452 /*
  453  * ask the scsi driver to perform a command for us.
  454  * tell it where to read/write the data, and how
  455  * long the data is supposed to be. If we have  a buf
  456  * to associate with the transfer, we need that too.
  457  */
  458 errval
  459 scsi_scsi_cmd(sc_link, scsi_cmd, cmdlen, data_addr, datalen,
  460     retries, timeout, bp, flags)
  461         struct scsi_link *sc_link;
  462         struct scsi_generic *scsi_cmd;
  463         u_int32_t cmdlen;
  464         u_char *data_addr;
  465         u_int32_t datalen;
  466         u_int32_t retries;
  467         u_int32_t timeout;
  468         struct buf *bp;
  469         u_int32_t flags;
  470 {
  471         struct scsi_xfer *xs;
  472         errval  retval;
  473         u_int32_t s;
  474 
  475         /*
  476          * Illegal command lengths will wedge host adapter software.
  477          * Reject zero length commands and assert all defined commands
  478          * are the correct length.
  479          */
  480         if ((flags & (SCSI_RESET | SCSI_ESCAPE)) == 0)
  481         {
  482                 if (cmdlen == 0)
  483                         return EFAULT;
  484                 else
  485                 {
  486                         static u_int8_t sizes[] = {6, 10, 10, 0, 0, 12, 0, 0 };
  487                         u_int8_t size = sizes[((scsi_cmd->opcode) >> 5)];
  488                         if (size && (size != cmdlen))
  489                                 return EIO;
  490                 }
  491         }
  492 
  493         SC_DEBUG(sc_link, SDEV_DB2, ("scsi_cmd\n"));
  494 
  495         xs = get_xs(sc_link, flags);
  496         if (!xs) return (ENOMEM);
  497         /*
  498          * Fill out the scsi_xfer structure.  We don't know whose context
  499          * the cmd is in, so copy it.
  500          */
  501         bcopy(scsi_cmd, &(xs->cmdstore), cmdlen);
  502         xs->flags = INUSE | flags;
  503         xs->sc_link = sc_link;
  504         xs->retries = retries;
  505         xs->timeout = timeout;
  506         xs->cmd = &xs->cmdstore;
  507         xs->cmdlen = cmdlen;
  508         xs->data = data_addr;
  509         xs->datalen = datalen;
  510         xs->resid = 0;
  511         xs->bp = bp;
  512 /*XXX*/ /*use constant not magic number */
  513         if (datalen && ((caddr_t) data_addr < (caddr_t) KERNBASE)) {
  514                 if (bp) {
  515                         printf("Data buffered space not in kernel context\n");
  516 #ifdef  SCSIDEBUG
  517                         show_scsi_cmd(xs);
  518 #endif  /* SCSIDEBUG */
  519                         retval = EFAULT;
  520                         goto bad;
  521                 }
  522 #ifdef BOUNCE_BUFFERS
  523                 xs->data = (caddr_t) vm_bounce_kva_alloc(btoc(datalen));
  524 #else
  525                 xs->data = malloc(datalen, M_TEMP, M_WAITOK);
  526 #endif
  527                 /* I think waiting is ok *//*XXX */
  528                 switch ((int)(flags & (SCSI_DATA_IN | SCSI_DATA_OUT))) {
  529                 case 0:
  530                         printf("No direction flags, assuming both\n");
  531 #ifdef  SCSIDEBUG
  532                         show_scsi_cmd(xs);
  533 #endif  /* SCSIDEBUG */
  534                 case SCSI_DATA_IN | SCSI_DATA_OUT:      /* weird */
  535                 case SCSI_DATA_OUT:
  536                         bcopy(data_addr, xs->data, datalen);
  537                         break;
  538                 case SCSI_DATA_IN:
  539                         bzero(xs->data, datalen);
  540                 }
  541         }
  542 retry:
  543         xs->error = XS_NOERROR;
  544 #ifdef  PARANOID
  545         if (datalen && ((caddr_t) xs->data < (caddr_t) KERNBASE)) {
  546                 printf("It's still wrong!\n");
  547         }
  548 #endif  /*PARANOID*/
  549 #ifdef  SCSIDEBUG
  550         if (sc_link->flags & SDEV_DB3) show_scsi_xs(xs);
  551 #endif /* SCSIDEBUG */
  552         /*
  553          * Do the transfer. If we are polling we will return:
  554          * COMPLETE,  Was poll, and scsi_done has been called
  555          * TRY_AGAIN_LATER, Adapter short resources, try again
  556          *
  557          * if under full steam (interrupts) it will return:
  558          * SUCCESSFULLY_QUEUED, will do a wakeup when complete
  559          * TRY_AGAIN_LATER, (as for polling)
  560          * After the wakeup, we must still check if it succeeded
  561          *
  562          * If we have a bp however, all the error proccessing
  563          * and the buffer code both expect us to return straight
  564          * to them, so as soon as the command is queued, return
  565          */
  566 
  567         retval = (*(sc_link->adapter->scsi_cmd)) (xs);
  568 
  569         switch (retval) {
  570         case SUCCESSFULLY_QUEUED:
  571                 if (bp) {
  572                         return 0;       /* will sleep (or not) elsewhere */
  573                 }
  574                 s = splbio();
  575                 while (!(xs->flags & ITSDONE)) {
  576                         tsleep((caddr_t)xs, PRIBIO + 1, "scsicmd", 0);
  577                 }
  578                 splx(s);
  579                 /* fall through to check success of completed command */
  580         case COMPLETE:          /* Polling command completed ok */
  581 /*XXX*/ case HAD_ERROR:         /* Polling command completed with error */
  582                 SC_DEBUG(sc_link, SDEV_DB3, ("back in cmd()\n"));
  583                 if ((retval = sc_err1(xs)) == SCSIRET_DO_RETRY)
  584                         goto retry;
  585                 break;
  586 
  587         case TRY_AGAIN_LATER:   /* adapter resource shortage */
  588                 SC_DEBUG(sc_link, SDEV_DB3, ("will try again \n"));
  589                 /* should sleep 1 sec here */
  590                 if (xs->retries--) {
  591                         xs->flags &= ~ITSDONE;
  592                         goto retry;
  593                 }
  594         default:
  595                 retval = EIO;
  596         }
  597         /*
  598          * If we had to copy the data out of the user's context,
  599          * then do the other half (copy it back or whatever)
  600          * and free the memory buffer
  601          */
  602         if (datalen && (xs->data != data_addr)) {
  603                 switch ((int)(flags & (SCSI_DATA_IN | SCSI_DATA_OUT))) {
  604                 case 0:
  605                 case SCSI_DATA_IN | SCSI_DATA_OUT:      /* weird */
  606                 case SCSI_DATA_IN:
  607                         bcopy(xs->data, data_addr, datalen);
  608                         break;
  609                 }
  610 #ifdef BOUNCE_BUFFERS
  611                 vm_bounce_kva_alloc_free((vm_offset_t) xs->data,
  612                                          btoc(datalen));
  613 #else
  614                 free(xs->data, M_TEMP);
  615 #endif
  616         }
  617         /*
  618          * we have finished with the xfer stuct, free it and
  619          * check if anyone else needs to be started up.
  620          */
  621 bad:
  622         s = splbio();
  623         free_xs(xs, sc_link, flags);    /* includes the 'start' op */
  624         splx(s);
  625         if (bp && retval) {
  626                 bp->b_error = retval;
  627                 bp->b_flags |= B_ERROR;
  628                 biodone(bp);
  629         }
  630         return (retval);
  631 }
  632 
  633 static errval
  634 sc_done(struct scsi_xfer *xs, int code)
  635 {
  636         /*
  637          * If it has a buf, we might be working with
  638          * a request from the buffer cache or some other
  639          * piece of code that requires us to process
  640          * errors at interrupt time. We have probably
  641          * been called by scsi_done()
  642          */
  643         struct buf *bp;
  644 
  645         if (code == SCSIRET_DO_RETRY) {
  646                 if (xs->retries--) {
  647                         xs->error = XS_NOERROR;
  648                         xs->flags &= ~ITSDONE;
  649                         return SCSIRET_DO_RETRY;
  650                 }
  651                 code = EIO;     /* Too many retries */
  652         }
  653 
  654         /*
  655          * an EOF condition results in a VALID resid..
  656          */
  657         if(xs->flags & SCSI_EOF) {
  658                 xs->resid = xs->datalen;
  659                 xs->flags |= SCSI_RESID_VALID;
  660         }
  661 
  662         bp = xs->bp;
  663         if (code != ESUCCESS) {
  664                 if (bp) {
  665                         bp->b_error = 0;
  666                         bp->b_flags |= B_ERROR;
  667                         bp->b_error = code;
  668                         bp->b_resid = bp->b_bcount;
  669                         SC_DEBUG(xs->sc_link, SDEV_DB3,
  670                                 ("scsi_interpret_sense (bp) returned %d\n", code));
  671                 } else {
  672                         SC_DEBUG(xs->sc_link, SDEV_DB3,
  673                                 ("scsi_interpret_sense (no bp) returned %d\n", code));
  674                 }
  675         }
  676         else {
  677                 if (bp) {
  678 
  679                         bp->b_error = 0;
  680 
  681                         /* XXX: We really shouldn't need this SCSI_RESID_VALID flag.
  682                          * If we initialize it to 0 and only touch it if we have
  683                          * a value then we can leave out the test.
  684                          */
  685 
  686                         if (xs->flags & SCSI_RESID_VALID) {
  687                                 bp->b_resid = xs->resid;
  688                                 bp->b_flags |= B_ERROR;
  689                         } else {
  690                                 bp->b_resid = 0;
  691                         }
  692                 }
  693         }
  694 
  695         return code;
  696 }
  697 
  698 /*
  699  * submit a scsi command, given the command.. used for retries
  700  * and callable from timeout()
  701  */
  702 #ifdef NOTYET
  703 errval scsi_submit(xs)
  704         struct scsi_xfer *xs;
  705 {
  706         struct scsi_link *sc_link = xs->sc_link;
  707         int retval;
  708 
  709         retval = (*(sc_link->adapter->scsi_cmd)) (xs);
  710 
  711         return retval;
  712 }
  713 
  714 /*
  715  * Retry a scsi command, given the command,  and a delay.
  716  */
  717 errval scsi_retry(xs,delay)
  718         struct scsi_xfer *xs;
  719         int     delay;
  720 {
  721         if(delay)
  722         {
  723                 timeout(((void())*)scsi_submit,xs,hz*delay);
  724                 return(0);
  725         }
  726         else
  727         {
  728                 return(scsi_submit(xs));
  729         }
  730 }
  731 #endif
  732 
  733 /*
  734  * handle checking for errors..
  735  * called at interrupt time from scsi_done() and
  736  * at user time from scsi_scsi_cmd(), depending on whether
  737  * there was a bp  (basically, if there is a bp, there may be no
  738  * associated process at the time. (it could be an async operation))
  739  * lower level routines shouldn't know about xs->bp.. we are the lowest.
  740  */
  741 static errval
  742 sc_err1(xs)
  743         struct scsi_xfer *xs;
  744 {
  745         SC_DEBUG(xs->sc_link, SDEV_DB3, ("sc_err1,err = 0x%lx \n", xs->error));
  746 
  747         switch ((int)xs->error) {
  748         case XS_SENSE:
  749                 return sc_done(xs, scsi_interpret_sense(xs));
  750 
  751         case XS_NOERROR:
  752                 return sc_done(xs, ESUCCESS);
  753 
  754         case XS_BUSY:
  755                 /* should somehow arange for a 1 sec delay here (how?)[jre]
  756                  * tsleep(&localvar, priority, "foo", hz);
  757                  * that's how! [unknown]
  758                  * no, we could be at interrupt context..  use
  759                  * timeout(scsi_resubmit,xs,hz); [jre] (not implimenteed yet)
  760                  */
  761                 DELAY(1000);
  762         case XS_TIMEOUT:
  763                 return sc_done(xs, SCSIRET_DO_RETRY);
  764 
  765                 /* fall through */
  766         case XS_SELTIMEOUT:
  767         case XS_DRIVER_STUFFUP:
  768                 return sc_done(xs, EIO);
  769 
  770         default:
  771                 sc_print_addr(xs->sc_link);
  772                 printf("unknown error category from scsi driver\n");
  773                 return sc_done(xs, EIO);
  774         }
  775 }
  776 
  777 #ifdef notyet
  778 static int
  779 scsi_sense_qualifiers(xs, asc, ascq)
  780         struct scsi_xfer *xs;
  781         int *asc;
  782         int *ascq;
  783 {
  784         struct scsi_sense_data_new *sense;
  785         struct scsi_sense_extended *ext;
  786 
  787         sense = (struct scsi_sense_data_new *)&(xs->sense);
  788 
  789         ext = &(sense->ext.extended);
  790 
  791         if (ext->extra_len < 5)
  792                 return 0;
  793 
  794         *asc = (ext->extra_len >= 5) ? ext->add_sense_code : 0;
  795         *ascq = (ext->extra_len >= 6) ? ext->add_sense_code_qual : 0;
  796 
  797         return 1;
  798 }
  799 
  800 #endif
  801 
  802 /*
  803  * scsi_sense_print will decode the sense data into human
  804  * readable form.  Sense handlers can use this to generate
  805  * a report.  This NOW DOES send the closing "\n".
  806  */
  807 void scsi_sense_print(xs)
  808         struct scsi_xfer *xs;
  809 {
  810         struct scsi_sense_data_new *sense;
  811         struct scsi_sense_extended *ext;
  812         u_int32_t key;
  813         u_int32_t info;
  814         int asc, ascq;
  815 
  816         /* This sense key text now matches what is in the SCSI spec
  817          * (Yes, even the capitals)
  818          * so that it is easier to look through the spec to find the
  819          * appropriate place.
  820          */
  821         static char *sense_key_text[] =
  822         {
  823             "NO SENSE", "RECOVERED ERROR",
  824             "NOT READY", "MEDIUM ERROR",
  825             "HARDWARE FAILURE", "ILLEGAL REQUEST",
  826             "UNIT ATTENTION", "DATA PROTECT",
  827             "BLANK CHECK", "Vendor Specific",
  828             "COPY ABORTED", "ABORTED COMMAND",
  829             "EQUAL", "VOLUME OVERFLOW",
  830             "MISCOMPARE", "RESERVED"
  831         };
  832 
  833         sc_print_start(xs->sc_link);
  834 
  835         sense = (struct scsi_sense_data_new *)&(xs->sense);
  836         ext = &(sense->ext.extended);
  837 
  838         key = ext->flags & SSD_KEY;
  839 
  840         switch (sense->error_code & SSD_ERRCODE) {
  841         case 0x71:              /* deferred error */
  842                 printf("Deferred Error: ");
  843 
  844                 /* DROP THROUGH */
  845 
  846         case 0x70:
  847 
  848                 printf("%s", sense_key_text[key]);
  849                 info = ntohl(*((long *) ext->info));
  850 
  851                 if (sense->error_code & SSD_ERRCODE_VALID) {
  852 
  853                         switch ((int)key) {
  854                         case 0x2:       /* NOT READY */
  855                         case 0x5:       /* ILLEGAL REQUEST */
  856                         case 0x6:       /* UNIT ATTENTION */
  857                         case 0x7:       /* DATA PROTECT */
  858                                 break;
  859                         case 0x8:       /* BLANK CHECK */
  860                                 printf(" req sz: %ld (decimal)",
  861                                     info);
  862                                 break;
  863                         default:
  864                                 if (info) {
  865                                 if (sense->ext.extended.flags & SSD_ILI) {
  866                                                 printf(" ILI (length mismatch): %ld", info);
  867                                         }
  868                                         else {
  869                                                 printf(" info:%#lx", info);
  870                                         }
  871                                 }
  872                         }
  873                 }
  874                 else if (info)
  875                         printf(" info?:%#lx", info);
  876 
  877                 if (ext->extra_len >= 4) {
  878                         if (bcmp(ext->cmd_spec_info, "\0\0\0\0", 4)) {
  879                                 printf(" csi:%x,%x,%x,%x",
  880                                 ext->cmd_spec_info[0],
  881                                 ext->cmd_spec_info[1],
  882                                 ext->cmd_spec_info[2],
  883                                 ext->cmd_spec_info[3]);
  884                         }
  885                 }
  886 
  887                 asc = (ext->extra_len >= 5) ? ext->add_sense_code : 0;
  888                 ascq = (ext->extra_len >= 6) ? ext->add_sense_code_qual : 0;
  889 
  890                 if (asc || ascq)
  891                 {
  892                         char *desc = scsi_sense_desc(asc, ascq);
  893                         printf(" asc:%x,%x", asc, ascq);
  894 
  895                         if (strlen(desc) > 40)
  896                                 sc_print_addr(xs->sc_link);;
  897 
  898                         printf(" %s", desc);
  899                 }
  900 
  901                 if (ext->extra_len >= 7 && ext->fru) {
  902                         printf(" field replaceable unit: %x", ext->fru);
  903                 }
  904 
  905                 if (ext->extra_len >= 10 &&
  906                 (ext->sense_key_spec_1 & SSD_SCS_VALID)) {
  907                         printf(" sks:%x,%x", ext->sense_key_spec_1,
  908                         (ext->sense_key_spec_2 |
  909                         ext->sense_key_spec_3));
  910                 }
  911                 break;
  912 
  913         /*
  914          * Not code 70, just report it
  915          */
  916         default:
  917                 printf("error code %d",
  918                     sense->error_code & SSD_ERRCODE);
  919                 if (sense->error_code & SSD_ERRCODE_VALID) {
  920                         printf(" at block no. %ld (decimal)",
  921                             (((unsigned long)sense->ext.unextended.blockhi) << 16) +
  922                             (((unsigned long)sense->ext.unextended.blockmed) << 8) +
  923                             ((unsigned long)sense->ext.unextended.blocklow));
  924                 }
  925         }
  926 
  927         printf("\n");
  928         sc_print_finish();
  929 }
  930 
  931 /*
  932  * Look at the returned sense and act on the error, determining
  933  * the unix error number to pass back.  (0 = report no error)
  934  *
  935  * THIS IS THE DEFAULT SENSE HANDLER
  936  */
  937 static errval
  938 scsi_interpret_sense(xs)
  939         struct scsi_xfer *xs;
  940 {
  941         struct scsi_sense_data_new *sense;
  942         struct scsi_sense_extended *ext;
  943         struct scsi_link *sc_link = xs->sc_link;
  944         u_int32_t key;
  945         u_int32_t silent;
  946         errval  errcode;
  947         int error_code, asc, ascq;
  948 
  949         /*
  950          * If the flags say errs are ok, then always return ok.
  951          * XXX: What if it is a deferred error?
  952          */
  953         if (xs->flags & SCSI_ERR_OK)
  954                 return (ESUCCESS);
  955 
  956         sense = (struct scsi_sense_data_new *)&(xs->sense);
  957         ext = &(sense->ext.extended);
  958 #ifdef  SCSIDEBUG
  959         if (sc_link->flags & SDEV_DB1) {
  960 
  961                 u_int32_t count = 0;
  962                 printf("code%x valid%x ",
  963                     sense->error_code & SSD_ERRCODE,
  964                     sense->error_code & SSD_ERRCODE_VALID ? 1 : 0);
  965                 printf("seg%x key%x ili%x eom%x fmark%x\n",
  966                     ext->segment,
  967                     ext->flags & SSD_KEY,
  968                     ext->flags & SSD_ILI ? 1 : 0,
  969                     ext->flags & SSD_EOM ? 1 : 0,
  970                     ext->flags & SSD_FILEMARK ? 1 : 0);
  971                 printf("info: %x %x %x %x followed by %d extra bytes\n",
  972                     ext->info[0],
  973                     ext->info[1],
  974                     ext->info[2],
  975                     ext->info[3],
  976                     ext->extra_len);
  977                 printf("extra: ");
  978                 while (count < ext->extra_len) {
  979                         printf("%x ", ext->extra_bytes[count++]);
  980                 }
  981                 printf("\n");
  982         }
  983   #endif        /*SCSIDEBUG */
  984         /*
  985          * If the device has it's own sense handler, call it first.
  986          * If it returns a legit errno value, return that, otherwise
  987          * it should return either DO_RETRY or CONTINUE to either
  988          * request a retry or continue with default sense handling.
  989          */
  990         if (sc_link->device->err_handler) {
  991                 SC_DEBUG(sc_link, SDEV_DB2,
  992                         ("calling private err_handler()\n"));
  993                 errcode = (*sc_link->device->err_handler) (xs);
  994 
  995                 SC_DEBUG(sc_link, SDEV_DB2,
  996                         ("private err_handler() returned %d\n",errcode));
  997                 if (errcode >= 0) {
  998                 SC_DEBUG(sc_link, SDEV_DB2,
  999                         ("SCSI_EOF = %d\n",(xs->flags & SCSI_EOF)?1:0));
 1000                 SC_DEBUG(sc_link, SDEV_DB2,
 1001                         ("SCSI_RESID_VALID = %d\n",
 1002                                 (xs->flags & SCSI_RESID_VALID)?1:0));
 1003 
 1004                         if(xs->flags & SCSI_EOF) {
 1005                                 xs->resid = xs->datalen;
 1006                                 xs->flags |= SCSI_RESID_VALID;
 1007                         }
 1008                         return errcode;                 /* valid errno value */
 1009                 }
 1010 
 1011                 switch(errcode) {
 1012                 case SCSIRET_DO_RETRY:  /* Requested a retry */
 1013                         return errcode;
 1014 
 1015                 case SCSIRET_CONTINUE:  /* Continue with default sense processing */
 1016                         break;
 1017 
 1018                 default:
 1019                         sc_print_addr(xs->sc_link);
 1020                         printf("unknown return code %d from sense handler.\n",
 1021                         errcode);
 1022 
 1023                         return errcode;
 1024                 }
 1025         }
 1026 
 1027         /* otherwise use the default */
 1028         silent = xs->flags & SCSI_SILENT;
 1029         key = ext->flags & SSD_KEY;
 1030         error_code = sense->error_code & SSD_ERRCODE;
 1031         asc = (ext->extra_len >= 5) ? ext->add_sense_code : 0;
 1032         ascq = (ext->extra_len >= 6) ? ext->add_sense_code_qual : 0;
 1033 
 1034         /*
 1035          * Retry while the device is returning a ``Logical unit
 1036          * is in the process of becoming ready.'' (until it either
 1037          * eventually yields an error, or finally succeeds).
 1038          */
 1039         if (error_code == 0x70 /* current error */ &&
 1040             (int)key == 0x2 /* not ready */ &&
 1041             asc == 4 && ascq == 1 /* logical unit i i t p o b r */)
 1042                 return (SCSIRET_DO_RETRY);
 1043 
 1044         if (!silent) {
 1045                 scsi_sense_print(xs);
 1046         }
 1047 
 1048         switch (error_code) {
 1049         case 0x71:              /* deferred error */
 1050                 /* Print even if silent (not silent was already done)
 1051                  */
 1052                 if (silent) {
 1053                         scsi_sense_print(xs);
 1054                 }
 1055 
 1056                 /* XXX:
 1057                  * This error doesn't relate to the command associated
 1058                  * with this request sense.  A deferred error is an error
 1059                  * for a command that has already returned GOOD status (see 7.2.14.2).
 1060                  *
 1061                  * By my reading of that section, it looks like the current command
 1062                  * has been cancelled, we should now clean things up (hopefully
 1063                  * recovering any lost data) and then
 1064                  * retry the current command.  There are two easy choices, both
 1065                  * wrong:
 1066                  * 1. Drop through (like we had been doing), thus treating this as
 1067                  * if the error were for the current command and return and stop
 1068                  * the current command.
 1069                  * 2. Issue a retry (like I made it do) thus hopefully recovering
 1070                  * the current transfer, and ignoring the fact that we've dropped
 1071                  * a command.
 1072                  *
 1073                  * These should probably be handled in a device specific
 1074                  * sense handler or punted back up to a user mode daemon
 1075                  */
 1076                 return SCSIRET_DO_RETRY;
 1077 
 1078                 /*
 1079                  * If it's code 70, use the extended stuff and interpret the key
 1080                  */
 1081         case 0x70:
 1082 
 1083                 switch ((int)key) {
 1084                 case 0x0:       /* NO SENSE */
 1085                 case 0x1:       /* RECOVERED ERROR */
 1086                 case 0xc:       /* EQUAL */
 1087                         if(xs->flags & SCSI_EOF) {
 1088                                 xs->resid = xs->datalen;
 1089                                 xs->flags |= SCSI_RESID_VALID;
 1090                         }
 1091                         return (ESUCCESS);
 1092                 case 0x2:       /* NOT READY */
 1093                         sc_link->flags &= ~SDEV_MEDIA_LOADED;
 1094                         return (EBUSY);
 1095                 case 0x5:       /* ILLEGAL REQUEST */
 1096                         return (EINVAL);
 1097                 case 0x6:       /* UNIT ATTENTION */
 1098                         sc_link->flags &= ~SDEV_MEDIA_LOADED;
 1099                         if (sc_link->flags & SDEV_OPEN) {
 1100                                 return (EIO);
 1101                         } else {
 1102                                 return 0;
 1103                         }
 1104                 case 0x7:       /* DATA PROTECT */
 1105                         return (EACCES);
 1106                 case 0xd:       /* VOLUME OVERFLOW */
 1107                         return (ENOSPC);
 1108                 case 0x8:       /* BLANK CHECK */
 1109                         xs->flags |= SCSI_EOF; /* force EOF on tape read */
 1110                         return (ESUCCESS);
 1111                 default:
 1112                         return (EIO);
 1113                 }
 1114         /*
 1115          * Not code 70, return EIO
 1116          */
 1117         default:
 1118                 return (EIO);
 1119         }
 1120 }
 1121 
 1122 /*
 1123  * Utility routines often used in SCSI stuff
 1124  */
 1125 
 1126 /*
 1127  * convert a physical address to 3 bytes,
 1128  * MSB at the lowest address,
 1129  * LSB at the highest.
 1130  */
 1131 void
 1132 scsi_uto3b(val, bytes)
 1133         u_int32_t       val;
 1134         u_char  *bytes;
 1135 {
 1136         *bytes++ = (val & 0xff0000) >> 16;
 1137         *bytes++ = (val & 0xff00) >> 8;
 1138         *bytes = val & 0xff;
 1139 }
 1140 
 1141 u_int32_t
 1142 scsi_3btou(bytes)
 1143         u_char *bytes;
 1144 {
 1145         u_int32_t rc;
 1146         rc = (*bytes++ << 16);
 1147         rc += (*bytes++ << 8);
 1148         rc += *bytes;
 1149         return rc;
 1150 }
 1151 
 1152 int32_t
 1153 scsi_3btoi(bytes)
 1154         u_char *bytes;
 1155 {
 1156         u_int32_t rc = scsi_3btou(bytes);
 1157 
 1158         if (rc & 0x00800000)
 1159                 rc |= 0xff000000;
 1160 
 1161         return (int32_t) rc;
 1162 }
 1163 
 1164 void
 1165 scsi_uto2b(val, bytes)
 1166         u_int32_t       val;
 1167         u_char  *bytes;
 1168 {
 1169         *bytes++ = (val & 0xff00) >> 8;
 1170         *bytes =    val & 0xff;
 1171 }
 1172 
 1173 u_int32_t
 1174 scsi_2btou(bytes)
 1175         u_char *bytes;
 1176 {
 1177         u_int32_t rc;
 1178         rc  = (*bytes++ << 8);
 1179         rc +=  *bytes;
 1180         return rc;
 1181 }
 1182 
 1183 void
 1184 scsi_uto4b(val, bytes)
 1185         u_int32_t       val;
 1186         u_char  *bytes;
 1187 {
 1188         *bytes++ = (val & 0xff000000) >> 24;
 1189         *bytes++ = (val & 0xff0000) >> 16;
 1190         *bytes++ = (val & 0xff00) >> 8;
 1191         *bytes =    val & 0xff;
 1192 }
 1193 
 1194 u_int32_t
 1195 scsi_4btou(bytes)
 1196         u_char *bytes;
 1197 {
 1198         u_int32_t rc;
 1199         rc  = (*bytes++ << 24);
 1200         rc += (*bytes++ << 16);
 1201         rc += (*bytes++ << 8);
 1202         rc +=  *bytes;
 1203         return rc;
 1204 }
 1205 
 1206 static sc_printing;
 1207 
 1208 void
 1209 sc_print_start(sc_link)
 1210         struct scsi_link *sc_link;
 1211 {
 1212         sc_print_addr(sc_link);
 1213         sc_printing++;
 1214 }
 1215 void
 1216 sc_print_finish()
 1217 {
 1218         sc_printing--;
 1219 }
 1220 
 1221 static void
 1222 id_put(int id, char *after)
 1223 {
 1224         switch(id)
 1225         {
 1226                 case SCCONF_UNSPEC:
 1227                 break;
 1228 
 1229                 case SCCONF_ANY:
 1230                 printf("?");
 1231                 break;
 1232 
 1233                 default:
 1234                 printf("%d", id);
 1235                 break;
 1236         }
 1237 
 1238         printf("%s", after);
 1239 }
 1240 
 1241 /*
 1242  * sc_print_addr: Print out the scsi_link structure's address info.
 1243  * This should handle any circumstance, even the transitory ones
 1244  * during system configuration.
 1245  */
 1246 
 1247 void
 1248 sc_print_addr(sc_link)
 1249         struct  scsi_link *sc_link;
 1250 {
 1251         if (sc_printing)
 1252                 printf("\n");
 1253 
 1254         if (sc_link->device == 0) {
 1255                 printf("nodevice");
 1256         }
 1257         else if (strcmp(sc_link->device->name, "probe") != 0) {
 1258                 printf("%s", sc_link->device->name);
 1259                 id_put(sc_link->dev_unit, "");
 1260         }
 1261 
 1262         if (sc_link->adapter == 0) {
 1263                 printf("(noadapter:");
 1264         }
 1265         else {
 1266                 printf("(%s", sc_link->adapter->name);
 1267                 id_put(sc_link->adapter_unit, ":");
 1268         }
 1269 
 1270         id_put(sc_link->target, ":");
 1271         id_put(sc_link->lun, "): ");
 1272 }
 1273 
 1274 #ifdef  SCSIDEBUG
 1275 /*
 1276  * Given a scsi_xfer, dump the request, in all it's glory
 1277  */
 1278 static void
 1279 show_scsi_xs(xs)
 1280         struct scsi_xfer *xs;
 1281 {
 1282         printf("xs(%p): ", xs);
 1283         printf("flg(0x%lx)", xs->flags);
 1284         printf("sc_link(%p)", xs->sc_link);
 1285         printf("retr(0x%x)", xs->retries);
 1286         printf("timo(0x%lx)", xs->timeout);
 1287         printf("cmd(%p)", xs->cmd);
 1288         printf("len(0x%lx)", xs->cmdlen);
 1289         printf("data(%p)", xs->data);
 1290         printf("len(0x%lx)", xs->datalen);
 1291         printf("res(0x%lx)", xs->resid);
 1292         printf("err(0x%lx)", xs->error);
 1293         printf("bp(%p)", xs->bp);
 1294         show_scsi_cmd(xs);
 1295 }
 1296 
 1297 void
 1298 show_scsi_cmd(struct scsi_xfer *xs)
 1299 {
 1300         u_char *b = (u_char *) xs->cmd;
 1301         int     i = 0;
 1302 
 1303         sc_print_addr(xs->sc_link);
 1304         printf("command: ");
 1305 
 1306         if (!(xs->flags & SCSI_RESET)) {
 1307                 while (i < xs->cmdlen) {
 1308                         if (i)
 1309                                 printf(",");
 1310                         printf("%x", b[i++]);
 1311                 }
 1312                 printf("-[%ld bytes]\n", xs->datalen);
 1313                 if (xs->datalen)
 1314                         show_mem(xs->data, min(64, xs->datalen));
 1315         } else {
 1316                 printf("-RESET-\n");
 1317         }
 1318 }
 1319 
 1320 static void
 1321 show_mem(address, num)
 1322         unsigned char *address;
 1323         u_int32_t num;
 1324 {
 1325         u_int32_t y;
 1326         printf("------------------------------");
 1327         for (y = 0; y < num; y += 1) {
 1328                 if (!(y % 16))
 1329                         printf("\n%03ld: ", y);
 1330                 printf("%02x ", *address++);
 1331         }
 1332         printf("\n------------------------------\n");
 1333 }
 1334 #endif /*SCSIDEBUG */

Cache object: e012f01738444e592750e8cb93fd21dc


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