The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/cam/ctl/ctl_error.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  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2003-2009 Silicon Graphics International Corp.
    5  * Copyright (c) 2011 Spectra Logic Corporation
    6  * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org>
    7  * All rights reserved.
    8  *
    9  * Redistribution and use in source and binary forms, with or without
   10  * modification, are permitted provided that the following conditions
   11  * are met:
   12  * 1. Redistributions of source code must retain the above copyright
   13  *    notice, this list of conditions, and the following disclaimer,
   14  *    without modification.
   15  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
   16  *    substantially similar to the "NO WARRANTY" disclaimer below
   17  *    ("Disclaimer") and any redistribution must be conditioned upon
   18  *    including a substantially similar Disclaimer requirement for further
   19  *    binary redistribution.
   20  *
   21  * NO WARRANTY
   22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
   25  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
   26  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
   30  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
   31  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   32  * POSSIBILITY OF SUCH DAMAGES.
   33  *
   34  * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_error.c#2 $
   35  */
   36 /*
   37  * CAM Target Layer error reporting routines.
   38  *
   39  * Author: Ken Merry <ken@FreeBSD.org>
   40  */
   41 
   42 #include <sys/cdefs.h>
   43 __FBSDID("$FreeBSD$");
   44 
   45 #include <sys/param.h>
   46 #include <sys/systm.h>
   47 #include <sys/kernel.h>
   48 #include <sys/types.h>
   49 #include <sys/malloc.h>
   50 #include <sys/lock.h>
   51 #include <sys/mutex.h>
   52 #include <sys/condvar.h>
   53 #include <sys/stddef.h>
   54 #include <sys/ctype.h>
   55 #include <sys/sysctl.h>
   56 #include <machine/stdarg.h>
   57 
   58 #include <cam/scsi/scsi_all.h>
   59 #include <cam/scsi/scsi_da.h>
   60 #include <cam/ctl/ctl_io.h>
   61 #include <cam/ctl/ctl.h>
   62 #include <cam/ctl/ctl_frontend.h>
   63 #include <cam/ctl/ctl_backend.h>
   64 #include <cam/ctl/ctl_ioctl.h>
   65 #include <cam/ctl/ctl_error.h>
   66 #include <cam/ctl/ctl_ha.h>
   67 #include <cam/ctl/ctl_private.h>
   68 
   69 void
   70 ctl_set_sense_data_va(struct scsi_sense_data *sense_data, u_int *sense_len,
   71     void *lunptr, scsi_sense_data_type sense_format, int current_error,
   72     int sense_key, int asc, int ascq, va_list ap)
   73 {
   74         struct ctl_lun *lun;
   75 
   76         lun = (struct ctl_lun *)lunptr;
   77 
   78         /*
   79          * Determine whether to return fixed or descriptor format sense
   80          * data.
   81          */
   82         if (sense_format == SSD_TYPE_NONE) {
   83                 /*
   84                  * SPC-3 and up require some UAs to be returned as fixed.
   85                  */
   86                 if (asc == 0x29 || (asc == 0x2A && ascq == 0x01))
   87                         sense_format = SSD_TYPE_FIXED;
   88                 else
   89                 /*
   90                  * If the format isn't specified, we only return descriptor
   91                  * sense if the LUN exists and descriptor sense is turned
   92                  * on for that LUN.
   93                  */
   94                 if ((lun != NULL) && (lun->MODE_CTRL.rlec & SCP_DSENSE))
   95                         sense_format = SSD_TYPE_DESC;
   96                 else
   97                         sense_format = SSD_TYPE_FIXED;
   98         }
   99 
  100         /*
  101          * Determine maximum sense data length to return.
  102          */
  103         if (*sense_len == 0) {
  104                 if ((lun != NULL) && (lun->MODE_CTRLE.max_sense != 0))
  105                         *sense_len = lun->MODE_CTRLE.max_sense;
  106                 else
  107                         *sense_len = SSD_FULL_SIZE;
  108         }
  109 
  110         scsi_set_sense_data_va(sense_data, sense_len, sense_format,
  111             current_error, sense_key, asc, ascq, ap);
  112 }
  113 
  114 void
  115 ctl_set_sense_data(struct scsi_sense_data *sense_data, u_int *sense_len,
  116     void *lunptr, scsi_sense_data_type sense_format, int current_error,
  117     int sense_key, int asc, int ascq, ...)
  118 {
  119         va_list ap;
  120 
  121         va_start(ap, ascq);
  122         ctl_set_sense_data_va(sense_data, sense_len, lunptr, sense_format,
  123             current_error, sense_key, asc, ascq, ap);
  124         va_end(ap);
  125 }
  126 
  127 void
  128 ctl_set_sense(struct ctl_scsiio *ctsio, int current_error, int sense_key,
  129               int asc, int ascq, ...)
  130 {
  131         va_list ap;
  132         struct ctl_lun *lun;
  133         u_int sense_len;
  134 
  135         /*
  136          * The LUN can't go away until all of the commands have been
  137          * completed.  Therefore we can safely access the LUN structure and
  138          * flags without the lock.
  139          */
  140         lun = CTL_LUN(ctsio);
  141 
  142         va_start(ap, ascq);
  143         sense_len = 0;
  144         ctl_set_sense_data_va(&ctsio->sense_data, &sense_len,
  145                               lun,
  146                               SSD_TYPE_NONE,
  147                               current_error,
  148                               sense_key,
  149                               asc,
  150                               ascq,
  151                               ap);
  152         va_end(ap);
  153 
  154         ctsio->scsi_status = SCSI_STATUS_CHECK_COND;
  155         ctsio->sense_len = sense_len;
  156         ctsio->io_hdr.status = CTL_SCSI_ERROR | CTL_AUTOSENSE;
  157 }
  158 
  159 /*
  160  * Transform fixed sense data into descriptor sense data.
  161  * 
  162  * For simplicity's sake, we assume that both sense structures are
  163  * SSD_FULL_SIZE.  Otherwise, the logic gets more complicated.
  164  */
  165 void
  166 ctl_sense_to_desc(struct scsi_sense_data_fixed *sense_src,
  167                   struct scsi_sense_data_desc *sense_dest)
  168 {
  169         struct scsi_sense_stream stream_sense;
  170         int current_error;
  171         u_int sense_len;
  172         uint8_t stream_bits;
  173 
  174         bzero(sense_dest, sizeof(*sense_dest));
  175 
  176         if ((sense_src->error_code & SSD_ERRCODE) == SSD_DEFERRED_ERROR)
  177                 current_error = 0;
  178         else
  179                 current_error = 1;
  180 
  181         bzero(&stream_sense, sizeof(stream_sense));
  182 
  183         /*
  184          * Check to see whether any of the tape-specific bits are set.  If
  185          * so, we'll need a stream sense descriptor.
  186          */
  187         if (sense_src->flags & (SSD_ILI|SSD_EOM|SSD_FILEMARK))
  188                 stream_bits = sense_src->flags & ~SSD_KEY;
  189         else
  190                 stream_bits = 0;
  191 
  192         /*
  193          * Utilize our sense setting routine to do the transform.  If a
  194          * value is set in the fixed sense data, set it in the descriptor
  195          * data.  Otherwise, skip it.
  196          */
  197         sense_len = SSD_FULL_SIZE;
  198         ctl_set_sense_data((struct scsi_sense_data *)sense_dest, &sense_len,
  199                            /*lun*/ NULL,
  200                            /*sense_format*/ SSD_TYPE_DESC,
  201                            current_error,
  202                            /*sense_key*/ sense_src->flags & SSD_KEY,
  203                            /*asc*/ sense_src->add_sense_code,
  204                            /*ascq*/ sense_src->add_sense_code_qual,
  205 
  206                            /* Information Bytes */
  207                            (sense_src->error_code & SSD_ERRCODE_VALID) ?
  208                            SSD_ELEM_INFO : SSD_ELEM_SKIP,
  209                            sizeof(sense_src->info),
  210                            sense_src->info,
  211 
  212                            /* Command specific bytes */
  213                            (scsi_4btoul(sense_src->cmd_spec_info) != 0) ?
  214                            SSD_ELEM_COMMAND : SSD_ELEM_SKIP,
  215                            sizeof(sense_src->cmd_spec_info),
  216                            sense_src->cmd_spec_info,
  217 
  218                            /* FRU */
  219                            (sense_src->fru != 0) ?
  220                            SSD_ELEM_FRU : SSD_ELEM_SKIP,
  221                            sizeof(sense_src->fru),
  222                            &sense_src->fru,
  223 
  224                            /* Sense Key Specific */
  225                            (sense_src->sense_key_spec[0] & SSD_SCS_VALID) ?
  226                            SSD_ELEM_SKS : SSD_ELEM_SKIP,
  227                            sizeof(sense_src->sense_key_spec),
  228                            sense_src->sense_key_spec,
  229 
  230                            /* Tape bits */
  231                            (stream_bits != 0) ?
  232                            SSD_ELEM_STREAM : SSD_ELEM_SKIP,
  233                            sizeof(stream_bits),
  234                            &stream_bits,
  235 
  236                            SSD_ELEM_NONE);
  237 }
  238 
  239 /*
  240  * Transform descriptor format sense data into fixed sense data.
  241  *
  242  * Some data may be lost in translation, because there are descriptors
  243  * thant can't be represented as fixed sense data.
  244  *
  245  * For simplicity's sake, we assume that both sense structures are
  246  * SSD_FULL_SIZE.  Otherwise, the logic gets more complicated.
  247  */
  248 void
  249 ctl_sense_to_fixed(struct scsi_sense_data_desc *sense_src,
  250                    struct scsi_sense_data_fixed *sense_dest)
  251 {
  252         int current_error;
  253         uint8_t *info_ptr = NULL, *cmd_ptr = NULL, *fru_ptr = NULL;
  254         uint8_t *sks_ptr = NULL, *stream_ptr = NULL;
  255         int info_size = 0, cmd_size = 0, fru_size = 0;
  256         int sks_size = 0, stream_size = 0;
  257         int pos;
  258         u_int sense_len;
  259 
  260         if ((sense_src->error_code & SSD_ERRCODE) == SSD_DESC_CURRENT_ERROR)
  261                 current_error = 1;
  262         else
  263                 current_error = 0;
  264 
  265         for (pos = 0; pos < (int)(sense_src->extra_len - 1);) {
  266                 struct scsi_sense_desc_header *header;
  267 
  268                 header = (struct scsi_sense_desc_header *)
  269                     &sense_src->sense_desc[pos];
  270 
  271                 /*
  272                  * See if this record goes past the end of the sense data.
  273                  * It shouldn't, but check just in case.
  274                  */
  275                 if ((pos + header->length + sizeof(*header)) >
  276                      sense_src->extra_len)
  277                         break;
  278 
  279                 switch (sense_src->sense_desc[pos]) {
  280                 case SSD_DESC_INFO: {
  281                         struct scsi_sense_info *info;
  282 
  283                         info = (struct scsi_sense_info *)header;
  284 
  285                         info_ptr = info->info;
  286                         info_size = sizeof(info->info);
  287 
  288                         pos += info->length +
  289                             sizeof(struct scsi_sense_desc_header);
  290                         break;
  291                 }
  292                 case SSD_DESC_COMMAND: {
  293                         struct scsi_sense_command *cmd;
  294 
  295                         cmd = (struct scsi_sense_command *)header;
  296                         cmd_ptr = cmd->command_info;
  297                         cmd_size = sizeof(cmd->command_info);
  298 
  299                         pos += cmd->length + 
  300                             sizeof(struct scsi_sense_desc_header);
  301                         break;
  302                 }
  303                 case SSD_DESC_FRU: {
  304                         struct scsi_sense_fru *fru;
  305 
  306                         fru = (struct scsi_sense_fru *)header;
  307                         fru_ptr = &fru->fru;
  308                         fru_size = sizeof(fru->fru);
  309                         pos += fru->length +
  310                             sizeof(struct scsi_sense_desc_header);
  311                         break;
  312                 }
  313                 case SSD_DESC_SKS: {
  314                         struct scsi_sense_sks *sks;
  315 
  316                         sks = (struct scsi_sense_sks *)header;
  317                         sks_ptr = sks->sense_key_spec;
  318                         sks_size = sizeof(sks->sense_key_spec);
  319 
  320                         pos = sks->length +
  321                             sizeof(struct scsi_sense_desc_header);
  322                         break;
  323                 }
  324                 case SSD_DESC_STREAM: {
  325                         struct scsi_sense_stream *stream_sense;
  326 
  327                         stream_sense = (struct scsi_sense_stream *)header;
  328                         stream_ptr = &stream_sense->byte3;
  329                         stream_size = sizeof(stream_sense->byte3);
  330                         pos = stream_sense->length +
  331                             sizeof(struct scsi_sense_desc_header);
  332                         break;
  333                 }
  334                 default:
  335                         /*
  336                          * We don't recognize this particular sense
  337                          * descriptor type, so just skip it.
  338                          */
  339                         pos += sizeof(*header) + header->length;
  340                         break;
  341                 }
  342         }
  343 
  344         sense_len = SSD_FULL_SIZE;
  345         ctl_set_sense_data((struct scsi_sense_data *)sense_dest, &sense_len,
  346                            /*lun*/ NULL,
  347                            /*sense_format*/ SSD_TYPE_FIXED,
  348                            current_error,
  349                            /*sense_key*/ sense_src->sense_key & SSD_KEY,
  350                            /*asc*/ sense_src->add_sense_code,
  351                            /*ascq*/ sense_src->add_sense_code_qual,
  352 
  353                            /* Information Bytes */ 
  354                            (info_ptr != NULL) ? SSD_ELEM_INFO : SSD_ELEM_SKIP,
  355                            info_size,
  356                            info_ptr,
  357 
  358                            /* Command specific bytes */
  359                            (cmd_ptr != NULL) ? SSD_ELEM_COMMAND : SSD_ELEM_SKIP,
  360                            cmd_size,
  361                            cmd_ptr,
  362 
  363                            /* FRU */
  364                            (fru_ptr != NULL) ? SSD_ELEM_FRU : SSD_ELEM_SKIP,
  365                            fru_size,
  366                            fru_ptr,
  367 
  368                            /* Sense Key Specific */
  369                            (sks_ptr != NULL) ? SSD_ELEM_SKS : SSD_ELEM_SKIP,
  370                            sks_size,
  371                            sks_ptr,
  372 
  373                            /* Tape bits */
  374                            (stream_ptr != NULL) ? SSD_ELEM_STREAM : SSD_ELEM_SKIP,
  375                            stream_size,
  376                            stream_ptr,
  377 
  378                            SSD_ELEM_NONE);
  379 }
  380 
  381 void
  382 ctl_set_ua(struct ctl_scsiio *ctsio, int asc, int ascq)
  383 {
  384         ctl_set_sense(ctsio,
  385                       /*current_error*/ 1,
  386                       /*sense_key*/ SSD_KEY_UNIT_ATTENTION,
  387                       asc,
  388                       ascq,
  389                       SSD_ELEM_NONE);
  390 }
  391 
  392 static void
  393 ctl_ua_to_ascq(struct ctl_lun *lun, ctl_ua_type ua_to_build, int *asc,
  394     int *ascq, ctl_ua_type *ua_to_clear, uint8_t **info)
  395 {
  396 
  397         switch (ua_to_build) {
  398         case CTL_UA_POWERON:
  399                 /* 29h/01h  POWER ON OCCURRED */
  400                 *asc = 0x29;
  401                 *ascq = 0x01;
  402                 *ua_to_clear = ~0;
  403                 break;
  404         case CTL_UA_BUS_RESET:
  405                 /* 29h/02h  SCSI BUS RESET OCCURRED */
  406                 *asc = 0x29;
  407                 *ascq = 0x02;
  408                 *ua_to_clear = ~0;
  409                 break;
  410         case CTL_UA_TARG_RESET:
  411                 /* 29h/03h  BUS DEVICE RESET FUNCTION OCCURRED*/
  412                 *asc = 0x29;
  413                 *ascq = 0x03;
  414                 *ua_to_clear = ~0;
  415                 break;
  416         case CTL_UA_I_T_NEXUS_LOSS:
  417                 /* 29h/07h  I_T NEXUS LOSS OCCURRED */
  418                 *asc = 0x29;
  419                 *ascq = 0x07;
  420                 *ua_to_clear = ~0;
  421                 break;
  422         case CTL_UA_LUN_RESET:
  423                 /* 29h/00h  POWER ON, RESET, OR BUS DEVICE RESET OCCURRED */
  424                 /*
  425                  * Since we don't have a specific ASC/ASCQ pair for a LUN
  426                  * reset, just return the generic reset code.
  427                  */
  428                 *asc = 0x29;
  429                 *ascq = 0x00;
  430                 break;
  431         case CTL_UA_LUN_CHANGE:
  432                 /* 3Fh/0Eh  REPORTED LUNS DATA HAS CHANGED */
  433                 *asc = 0x3F;
  434                 *ascq = 0x0E;
  435                 break;
  436         case CTL_UA_MODE_CHANGE:
  437                 /* 2Ah/01h  MODE PARAMETERS CHANGED */
  438                 *asc = 0x2A;
  439                 *ascq = 0x01;
  440                 break;
  441         case CTL_UA_LOG_CHANGE:
  442                 /* 2Ah/02h  LOG PARAMETERS CHANGED */
  443                 *asc = 0x2A;
  444                 *ascq = 0x02;
  445                 break;
  446         case CTL_UA_INQ_CHANGE:
  447                 /* 3Fh/03h  INQUIRY DATA HAS CHANGED */
  448                 *asc = 0x3F;
  449                 *ascq = 0x03;
  450                 break;
  451         case CTL_UA_RES_PREEMPT:
  452                 /* 2Ah/03h  RESERVATIONS PREEMPTED */
  453                 *asc = 0x2A;
  454                 *ascq = 0x03;
  455                 break;
  456         case CTL_UA_RES_RELEASE:
  457                 /* 2Ah/04h  RESERVATIONS RELEASED */
  458                 *asc = 0x2A;
  459                 *ascq = 0x04;
  460                 break;
  461         case CTL_UA_REG_PREEMPT:
  462                 /* 2Ah/05h  REGISTRATIONS PREEMPTED */
  463                 *asc = 0x2A;
  464                 *ascq = 0x05;
  465                 break;
  466         case CTL_UA_ASYM_ACC_CHANGE:
  467                 /* 2Ah/06h  ASYMMETRIC ACCESS STATE CHANGED */
  468                 *asc = 0x2A;
  469                 *ascq = 0x06;
  470                 break;
  471         case CTL_UA_CAPACITY_CHANGE:
  472                 /* 2Ah/09h  CAPACITY DATA HAS CHANGED */
  473                 *asc = 0x2A;
  474                 *ascq = 0x09;
  475                 break;
  476         case CTL_UA_THIN_PROV_THRES:
  477                 /* 38h/07h  THIN PROVISIONING SOFT THRESHOLD REACHED */
  478                 *asc = 0x38;
  479                 *ascq = 0x07;
  480                 *info = lun->ua_tpt_info;
  481                 break;
  482         case CTL_UA_MEDIUM_CHANGE:
  483                 /* 28h/00h  NOT READY TO READY CHANGE, MEDIUM MAY HAVE CHANGED */
  484                 *asc = 0x28;
  485                 *ascq = 0x00;
  486                 break;
  487         case CTL_UA_IE:
  488                 /* Informational exception */
  489                 *asc = lun->ie_asc;
  490                 *ascq = lun->ie_ascq;
  491                 break;
  492         default:
  493                 panic("%s: Unknown UA %x", __func__, ua_to_build);
  494         }
  495 }
  496 
  497 ctl_ua_type
  498 ctl_build_qae(struct ctl_lun *lun, uint32_t initidx, uint8_t *resp)
  499 {
  500         ctl_ua_type ua;
  501         ctl_ua_type ua_to_build, ua_to_clear;
  502         uint8_t *info;
  503         int asc, ascq;
  504         uint32_t p, i;
  505 
  506         mtx_assert(&lun->lun_lock, MA_OWNED);
  507         p = initidx / CTL_MAX_INIT_PER_PORT;
  508         i = initidx % CTL_MAX_INIT_PER_PORT;
  509         if (lun->pending_ua[p] == NULL)
  510                 ua = CTL_UA_POWERON;
  511         else
  512                 ua = lun->pending_ua[p][i];
  513         if (ua == CTL_UA_NONE)
  514                 return (CTL_UA_NONE);
  515 
  516         ua_to_build = (1 << (ffs(ua) - 1));
  517         ua_to_clear = ua_to_build;
  518         info = NULL;
  519         ctl_ua_to_ascq(lun, ua_to_build, &asc, &ascq, &ua_to_clear, &info);
  520 
  521         resp[0] = SSD_KEY_UNIT_ATTENTION;
  522         if (ua_to_build == ua)
  523                 resp[0] |= 0x10;
  524         else
  525                 resp[0] |= 0x20;
  526         resp[1] = asc;
  527         resp[2] = ascq;
  528         return (ua_to_build);
  529 }
  530 
  531 ctl_ua_type
  532 ctl_build_ua(struct ctl_lun *lun, uint32_t initidx,
  533     struct scsi_sense_data *sense, u_int *sense_len,
  534     scsi_sense_data_type sense_format)
  535 {
  536         ctl_ua_type *ua;
  537         ctl_ua_type ua_to_build, ua_to_clear;
  538         uint8_t *info;
  539         int asc, ascq;
  540         uint32_t p, i;
  541 
  542         mtx_assert(&lun->lun_lock, MA_OWNED);
  543         mtx_assert(&lun->ctl_softc->ctl_lock, MA_NOTOWNED);
  544         p = initidx / CTL_MAX_INIT_PER_PORT;
  545         if ((ua = lun->pending_ua[p]) == NULL) {
  546                 mtx_unlock(&lun->lun_lock);
  547                 ua = malloc(sizeof(ctl_ua_type) * CTL_MAX_INIT_PER_PORT,
  548                     M_CTL, M_WAITOK);
  549                 mtx_lock(&lun->lun_lock);
  550                 if (lun->pending_ua[p] == NULL) {
  551                         lun->pending_ua[p] = ua;
  552                         for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++)
  553                                 ua[i] = CTL_UA_POWERON;
  554                 } else {
  555                         free(ua, M_CTL);
  556                         ua = lun->pending_ua[p];
  557                 }
  558         }
  559         i = initidx % CTL_MAX_INIT_PER_PORT;
  560         if (ua[i] == CTL_UA_NONE)
  561                 return (CTL_UA_NONE);
  562 
  563         ua_to_build = (1 << (ffs(ua[i]) - 1));
  564         ua_to_clear = ua_to_build;
  565         info = NULL;
  566         ctl_ua_to_ascq(lun, ua_to_build, &asc, &ascq, &ua_to_clear, &info);
  567 
  568         ctl_set_sense_data(sense, sense_len, lun, sense_format, 1,
  569             /*sense_key*/ SSD_KEY_UNIT_ATTENTION, asc, ascq,
  570             ((info != NULL) ? SSD_ELEM_INFO : SSD_ELEM_SKIP), 8, info,
  571             SSD_ELEM_NONE);
  572 
  573         /* We're reporting this UA, so clear it */
  574         ua[i] &= ~ua_to_clear;
  575 
  576         if (ua_to_build == CTL_UA_LUN_CHANGE) {
  577                 mtx_unlock(&lun->lun_lock);
  578                 mtx_lock(&lun->ctl_softc->ctl_lock);
  579                 ctl_clr_ua_allluns(lun->ctl_softc, initidx, ua_to_build);
  580                 mtx_unlock(&lun->ctl_softc->ctl_lock);
  581                 mtx_lock(&lun->lun_lock);
  582         } else if (ua_to_build == CTL_UA_THIN_PROV_THRES &&
  583             (lun->MODE_LBP.main.flags & SLBPP_SITUA) != 0) {
  584                 ctl_clr_ua_all(lun, -1, ua_to_build);
  585         }
  586 
  587         return (ua_to_build);
  588 }
  589 
  590 void
  591 ctl_set_overlapped_cmd(struct ctl_scsiio *ctsio)
  592 {
  593         /* OVERLAPPED COMMANDS ATTEMPTED */
  594         ctl_set_sense(ctsio,
  595                       /*current_error*/ 1,
  596                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
  597                       /*asc*/ 0x4E,
  598                       /*ascq*/ 0x00,
  599                       SSD_ELEM_NONE);
  600 }
  601 
  602 void
  603 ctl_set_overlapped_tag(struct ctl_scsiio *ctsio, uint8_t tag)
  604 {
  605         /* TAGGED OVERLAPPED COMMANDS (NN = QUEUE TAG) */
  606         ctl_set_sense(ctsio,
  607                       /*current_error*/ 1,
  608                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
  609                       /*asc*/ 0x4D,
  610                       /*ascq*/ tag,
  611                       SSD_ELEM_NONE);
  612 }
  613 
  614 /*
  615  * Tell the user that there was a problem with the command or data he sent.
  616  */
  617 void
  618 ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command,
  619                       int field, int bit_valid, int bit)
  620 {
  621         uint8_t sks[3];
  622         int asc;
  623 
  624         if (command != 0) {
  625                 /* "Invalid field in CDB" */
  626                 asc = 0x24;
  627         } else {
  628                 /* "Invalid field in parameter list" */
  629                 asc = 0x26;
  630         }
  631 
  632         if (sks_valid) {
  633                 sks[0] = SSD_SCS_VALID;
  634                 if (command)
  635                         sks[0] |= SSD_FIELDPTR_CMD;
  636                 scsi_ulto2b(field, &sks[1]);
  637 
  638                 if (bit_valid)
  639                         sks[0] |= SSD_BITPTR_VALID | bit;
  640         }
  641 
  642         ctl_set_sense(ctsio,
  643                       /*current_error*/ 1,
  644                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
  645                       asc,
  646                       /*ascq*/ 0x00,
  647                       /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP,
  648                       /*size*/ sizeof(sks),
  649                       /*data*/ sks,
  650                       SSD_ELEM_NONE);
  651 }
  652 void
  653 ctl_set_invalid_field_ciu(struct ctl_scsiio *ctsio)
  654 {
  655 
  656         /* "Invalid field in command information unit" */
  657         ctl_set_sense(ctsio,
  658                       /*current_error*/ 1,
  659                       /*sense_key*/ SSD_KEY_ABORTED_COMMAND,
  660                       /*ascq*/ 0x0E,
  661                       /*ascq*/ 0x03,
  662                       SSD_ELEM_NONE);
  663 }
  664 
  665 void
  666 ctl_set_invalid_opcode(struct ctl_scsiio *ctsio)
  667 {
  668         uint8_t sks[3];
  669 
  670         sks[0] = SSD_SCS_VALID | SSD_FIELDPTR_CMD;
  671         scsi_ulto2b(0, &sks[1]);
  672 
  673         /* "Invalid command operation code" */
  674         ctl_set_sense(ctsio,
  675                       /*current_error*/ 1,
  676                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
  677                       /*asc*/ 0x20,
  678                       /*ascq*/ 0x00,
  679                       /*type*/ SSD_ELEM_SKS,
  680                       /*size*/ sizeof(sks),
  681                       /*data*/ sks,
  682                       SSD_ELEM_NONE);
  683 }
  684 
  685 void
  686 ctl_set_param_len_error(struct ctl_scsiio *ctsio)
  687 {
  688         /* "Parameter list length error" */
  689         ctl_set_sense(ctsio,
  690                       /*current_error*/ 1,
  691                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
  692                       /*asc*/ 0x1a,
  693                       /*ascq*/ 0x00,
  694                       SSD_ELEM_NONE);
  695 }
  696 
  697 void
  698 ctl_set_already_locked(struct ctl_scsiio *ctsio)
  699 {
  700         /* Vendor unique "Somebody already is locked" */
  701         ctl_set_sense(ctsio,
  702                       /*current_error*/ 1,
  703                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
  704                       /*asc*/ 0x81,
  705                       /*ascq*/ 0x00,
  706                       SSD_ELEM_NONE);
  707 }
  708 
  709 void
  710 ctl_set_unsupported_lun(struct ctl_scsiio *ctsio)
  711 {
  712         /* "Logical unit not supported" */
  713         ctl_set_sense(ctsio,
  714                       /*current_error*/ 1,
  715                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
  716                       /*asc*/ 0x25,
  717                       /*ascq*/ 0x00,
  718                       SSD_ELEM_NONE);
  719 }
  720 
  721 void
  722 ctl_set_internal_failure(struct ctl_scsiio *ctsio, int sks_valid,
  723                          uint16_t retry_count)
  724 {
  725         uint8_t sks[3];
  726 
  727         if (sks_valid) {
  728                 sks[0] = SSD_SCS_VALID;
  729                 sks[1] = (retry_count >> 8) & 0xff;
  730                 sks[2] = retry_count & 0xff;
  731         }
  732 
  733         /* "Internal target failure" */
  734         ctl_set_sense(ctsio,
  735                       /*current_error*/ 1,
  736                       /*sense_key*/ SSD_KEY_HARDWARE_ERROR,
  737                       /*asc*/ 0x44,
  738                       /*ascq*/ 0x00,
  739                       /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP,
  740                       /*size*/ sizeof(sks),
  741                       /*data*/ sks,
  742                       SSD_ELEM_NONE);
  743 }
  744 
  745 void
  746 ctl_set_medium_error(struct ctl_scsiio *ctsio, int read)
  747 {
  748         if (read) {
  749                 /* "Unrecovered read error" */
  750                 ctl_set_sense(ctsio,
  751                               /*current_error*/ 1,
  752                               /*sense_key*/ SSD_KEY_MEDIUM_ERROR,
  753                               /*asc*/ 0x11,
  754                               /*ascq*/ 0x00,
  755                               SSD_ELEM_NONE);
  756         } else {
  757                 /* "Write error - auto reallocation failed" */
  758                 ctl_set_sense(ctsio,
  759                               /*current_error*/ 1,
  760                               /*sense_key*/ SSD_KEY_MEDIUM_ERROR,
  761                               /*asc*/ 0x0C,
  762                               /*ascq*/ 0x02,
  763                               SSD_ELEM_NONE);
  764         }
  765 }
  766 
  767 void
  768 ctl_set_aborted(struct ctl_scsiio *ctsio)
  769 {
  770         ctl_set_sense(ctsio,
  771                       /*current_error*/ 1,
  772                       /*sense_key*/ SSD_KEY_ABORTED_COMMAND,
  773                       /*asc*/ 0x45,
  774                       /*ascq*/ 0x00,
  775                       SSD_ELEM_NONE);
  776 }
  777 
  778 void
  779 ctl_set_lba_out_of_range(struct ctl_scsiio *ctsio, uint64_t lba)
  780 {
  781         uint8_t info[8];
  782 
  783         scsi_u64to8b(lba, info);
  784 
  785         /* "Logical block address out of range" */
  786         ctl_set_sense(ctsio,
  787                       /*current_error*/ 1,
  788                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
  789                       /*asc*/ 0x21,
  790                       /*ascq*/ 0x00,
  791                       /*type*/ (lba != 0) ? SSD_ELEM_INFO : SSD_ELEM_SKIP,
  792                       /*size*/ sizeof(info), /*data*/ &info,
  793                       SSD_ELEM_NONE);
  794 }
  795 
  796 void
  797 ctl_set_lun_stopped(struct ctl_scsiio *ctsio)
  798 {
  799         /* "Logical unit not ready, initializing cmd. required" */
  800         ctl_set_sense(ctsio,
  801                       /*current_error*/ 1,
  802                       /*sense_key*/ SSD_KEY_NOT_READY,
  803                       /*asc*/ 0x04,
  804                       /*ascq*/ 0x02,
  805                       SSD_ELEM_NONE);
  806 }
  807 
  808 void
  809 ctl_set_lun_int_reqd(struct ctl_scsiio *ctsio)
  810 {
  811         /* "Logical unit not ready, manual intervention required" */
  812         ctl_set_sense(ctsio,
  813                       /*current_error*/ 1,
  814                       /*sense_key*/ SSD_KEY_NOT_READY,
  815                       /*asc*/ 0x04,
  816                       /*ascq*/ 0x03,
  817                       SSD_ELEM_NONE);
  818 }
  819 
  820 void
  821 ctl_set_lun_ejected(struct ctl_scsiio *ctsio)
  822 {
  823         /* "Medium not present - tray open" */
  824         ctl_set_sense(ctsio,
  825                       /*current_error*/ 1,
  826                       /*sense_key*/ SSD_KEY_NOT_READY,
  827                       /*asc*/ 0x3A,
  828                       /*ascq*/ 0x02,
  829                       SSD_ELEM_NONE);
  830 }
  831 
  832 void
  833 ctl_set_lun_no_media(struct ctl_scsiio *ctsio)
  834 {
  835         /* "Medium not present - tray closed" */
  836         ctl_set_sense(ctsio,
  837                       /*current_error*/ 1,
  838                       /*sense_key*/ SSD_KEY_NOT_READY,
  839                       /*asc*/ 0x3A,
  840                       /*ascq*/ 0x01,
  841                       SSD_ELEM_NONE);
  842 }
  843 
  844 void
  845 ctl_set_illegal_pr_release(struct ctl_scsiio *ctsio)
  846 {
  847         /* "Invalid release of persistent reservation" */
  848         ctl_set_sense(ctsio,
  849                       /*current_error*/ 1,
  850                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
  851                       /*asc*/ 0x26,
  852                       /*ascq*/ 0x04,
  853                       SSD_ELEM_NONE);
  854 }
  855 
  856 void
  857 ctl_set_lun_transit(struct ctl_scsiio *ctsio)
  858 {
  859         /* "Logical unit not ready, asymmetric access state transition" */
  860         ctl_set_sense(ctsio,
  861                       /*current_error*/ 1,
  862                       /*sense_key*/ SSD_KEY_NOT_READY,
  863                       /*asc*/ 0x04,
  864                       /*ascq*/ 0x0a,
  865                       SSD_ELEM_NONE);
  866 }
  867 
  868 void
  869 ctl_set_lun_standby(struct ctl_scsiio *ctsio)
  870 {
  871         /* "Logical unit not ready, target port in standby state" */
  872         ctl_set_sense(ctsio,
  873                       /*current_error*/ 1,
  874                       /*sense_key*/ SSD_KEY_NOT_READY,
  875                       /*asc*/ 0x04,
  876                       /*ascq*/ 0x0b,
  877                       SSD_ELEM_NONE);
  878 }
  879 
  880 void
  881 ctl_set_lun_unavail(struct ctl_scsiio *ctsio)
  882 {
  883         /* "Logical unit not ready, target port in unavailable state" */
  884         ctl_set_sense(ctsio,
  885                       /*current_error*/ 1,
  886                       /*sense_key*/ SSD_KEY_NOT_READY,
  887                       /*asc*/ 0x04,
  888                       /*ascq*/ 0x0c,
  889                       SSD_ELEM_NONE);
  890 }
  891 
  892 void
  893 ctl_set_medium_format_corrupted(struct ctl_scsiio *ctsio)
  894 {
  895         /* "Medium format corrupted" */
  896         ctl_set_sense(ctsio,
  897                       /*current_error*/ 1,
  898                       /*sense_key*/ SSD_KEY_MEDIUM_ERROR,
  899                       /*asc*/ 0x31,
  900                       /*ascq*/ 0x00,
  901                       SSD_ELEM_NONE);
  902 }
  903 
  904 void
  905 ctl_set_medium_magazine_inaccessible(struct ctl_scsiio *ctsio)
  906 {
  907         /* "Medium magazine not accessible" */
  908         ctl_set_sense(ctsio,
  909                       /*current_error*/ 1,
  910                       /*sense_key*/ SSD_KEY_NOT_READY,
  911                       /*asc*/ 0x3b,
  912                       /*ascq*/ 0x11,
  913                       SSD_ELEM_NONE);
  914 }
  915 
  916 void
  917 ctl_set_data_phase_error(struct ctl_scsiio *ctsio)
  918 {
  919         /* "Data phase error" */
  920         ctl_set_sense(ctsio,
  921                       /*current_error*/ 1,
  922                       /*sense_key*/ SSD_KEY_NOT_READY,
  923                       /*asc*/ 0x4b,
  924                       /*ascq*/ 0x00,
  925                       SSD_ELEM_NONE);
  926 }
  927 
  928 void
  929 ctl_set_reservation_conflict(struct ctl_scsiio *ctsio)
  930 {
  931 
  932         ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
  933         ctsio->sense_len = 0;
  934         ctsio->io_hdr.status = CTL_SCSI_ERROR;
  935 }
  936 
  937 void
  938 ctl_set_queue_full(struct ctl_scsiio *ctsio)
  939 {
  940 
  941         ctsio->scsi_status = SCSI_STATUS_QUEUE_FULL;
  942         ctsio->sense_len = 0;
  943         ctsio->io_hdr.status = CTL_SCSI_ERROR;
  944 }
  945 
  946 void
  947 ctl_set_busy(struct ctl_scsiio *ctsio)
  948 {
  949 
  950         ctsio->scsi_status = SCSI_STATUS_BUSY;
  951         ctsio->sense_len = 0;
  952         ctsio->io_hdr.status = CTL_SCSI_ERROR;
  953 }
  954 
  955 void
  956 ctl_set_task_aborted(struct ctl_scsiio *ctsio)
  957 {
  958 
  959         ctsio->scsi_status = SCSI_STATUS_TASK_ABORTED;
  960         ctsio->sense_len = 0;
  961         ctsio->io_hdr.status = CTL_CMD_ABORTED;
  962 }
  963 
  964 void
  965 ctl_set_hw_write_protected(struct ctl_scsiio *ctsio)
  966 {
  967         /* "Hardware write protected" */
  968         ctl_set_sense(ctsio,
  969                       /*current_error*/ 1,
  970                       /*sense_key*/ SSD_KEY_DATA_PROTECT,
  971                       /*asc*/ 0x27,
  972                       /*ascq*/ 0x01,
  973                       SSD_ELEM_NONE);
  974 }
  975 
  976 void
  977 ctl_set_space_alloc_fail(struct ctl_scsiio *ctsio)
  978 {
  979         /* "Space allocation failed write protect" */
  980         ctl_set_sense(ctsio,
  981                       /*current_error*/ 1,
  982                       /*sense_key*/ SSD_KEY_DATA_PROTECT,
  983                       /*asc*/ 0x27,
  984                       /*ascq*/ 0x07,
  985                       SSD_ELEM_NONE);
  986 }
  987 
  988 void
  989 ctl_set_success(struct ctl_scsiio *ctsio)
  990 {
  991 
  992         ctsio->scsi_status = SCSI_STATUS_OK;
  993         ctsio->sense_len = 0;
  994         ctsio->io_hdr.status = CTL_SUCCESS;
  995 }

Cache object: 15a7185dc647cee1f5da19770a8e7423


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