1130f4520SKenneth D. Merry /*- 2130f4520SKenneth D. Merry * Copyright (c) 2003-2009 Silicon Graphics International Corp. 3130f4520SKenneth D. Merry * Copyright (c) 2011 Spectra Logic Corporation 4130f4520SKenneth D. Merry * All rights reserved. 5130f4520SKenneth D. Merry * 6130f4520SKenneth D. Merry * Redistribution and use in source and binary forms, with or without 7130f4520SKenneth D. Merry * modification, are permitted provided that the following conditions 8130f4520SKenneth D. Merry * are met: 9130f4520SKenneth D. Merry * 1. Redistributions of source code must retain the above copyright 10130f4520SKenneth D. Merry * notice, this list of conditions, and the following disclaimer, 11130f4520SKenneth D. Merry * without modification. 12130f4520SKenneth D. Merry * 2. Redistributions in binary form must reproduce at minimum a disclaimer 13130f4520SKenneth D. Merry * substantially similar to the "NO WARRANTY" disclaimer below 14130f4520SKenneth D. Merry * ("Disclaimer") and any redistribution must be conditioned upon 15130f4520SKenneth D. Merry * including a substantially similar Disclaimer requirement for further 16130f4520SKenneth D. Merry * binary redistribution. 17130f4520SKenneth D. Merry * 18130f4520SKenneth D. Merry * NO WARRANTY 19130f4520SKenneth D. Merry * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20130f4520SKenneth D. Merry * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21130f4520SKenneth D. Merry * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 22130f4520SKenneth D. Merry * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23130f4520SKenneth D. Merry * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24130f4520SKenneth D. Merry * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25130f4520SKenneth D. Merry * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26130f4520SKenneth D. Merry * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27130f4520SKenneth D. Merry * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 28130f4520SKenneth D. Merry * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29130f4520SKenneth D. Merry * POSSIBILITY OF SUCH DAMAGES. 30130f4520SKenneth D. Merry * 31130f4520SKenneth D. Merry * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_error.c#2 $ 32130f4520SKenneth D. Merry */ 33130f4520SKenneth D. Merry /* 34130f4520SKenneth D. Merry * CAM Target Layer error reporting routines. 35130f4520SKenneth D. Merry * 36130f4520SKenneth D. Merry * Author: Ken Merry <ken@FreeBSD.org> 37130f4520SKenneth D. Merry */ 38130f4520SKenneth D. Merry 39130f4520SKenneth D. Merry #include <sys/cdefs.h> 40130f4520SKenneth D. Merry __FBSDID("$FreeBSD$"); 41130f4520SKenneth D. Merry 42130f4520SKenneth D. Merry #include <sys/param.h> 43130f4520SKenneth D. Merry #include <sys/systm.h> 44130f4520SKenneth D. Merry #include <sys/kernel.h> 45130f4520SKenneth D. Merry #include <sys/types.h> 46130f4520SKenneth D. Merry #include <sys/malloc.h> 47130f4520SKenneth D. Merry #include <sys/lock.h> 48130f4520SKenneth D. Merry #include <sys/mutex.h> 49130f4520SKenneth D. Merry #include <sys/condvar.h> 50130f4520SKenneth D. Merry #include <sys/stddef.h> 51130f4520SKenneth D. Merry #include <sys/ctype.h> 52bf8f8f34SKenneth D. Merry #include <sys/sysctl.h> 53130f4520SKenneth D. Merry #include <machine/stdarg.h> 54130f4520SKenneth D. Merry 55130f4520SKenneth D. Merry #include <cam/scsi/scsi_all.h> 56130f4520SKenneth D. Merry #include <cam/scsi/scsi_da.h> 57130f4520SKenneth D. Merry #include <cam/ctl/ctl_io.h> 58130f4520SKenneth D. Merry #include <cam/ctl/ctl.h> 59130f4520SKenneth D. Merry #include <cam/ctl/ctl_frontend.h> 60130f4520SKenneth D. Merry #include <cam/ctl/ctl_backend.h> 61130f4520SKenneth D. Merry #include <cam/ctl/ctl_ioctl.h> 62130f4520SKenneth D. Merry #include <cam/ctl/ctl_error.h> 63130f4520SKenneth D. Merry #include <cam/ctl/ctl_ha.h> 64130f4520SKenneth D. Merry #include <cam/ctl/ctl_private.h> 65130f4520SKenneth D. Merry 66130f4520SKenneth D. Merry void 67130f4520SKenneth D. Merry ctl_set_sense_data_va(struct scsi_sense_data *sense_data, void *lunptr, 68130f4520SKenneth D. Merry scsi_sense_data_type sense_format, int current_error, 69130f4520SKenneth D. Merry int sense_key, int asc, int ascq, va_list ap) 70130f4520SKenneth D. Merry { 71130f4520SKenneth D. Merry struct ctl_lun *lun; 72130f4520SKenneth D. Merry 73130f4520SKenneth D. Merry lun = (struct ctl_lun *)lunptr; 74130f4520SKenneth D. Merry 75130f4520SKenneth D. Merry /* 76130f4520SKenneth D. Merry * Determine whether to return fixed or descriptor format sense 77130f4520SKenneth D. Merry * data. 78130f4520SKenneth D. Merry */ 79130f4520SKenneth D. Merry if (sense_format == SSD_TYPE_NONE) { 80130f4520SKenneth D. Merry /* 81130f4520SKenneth D. Merry * If the format isn't specified, we only return descriptor 82130f4520SKenneth D. Merry * sense if the LUN exists and descriptor sense is turned 83130f4520SKenneth D. Merry * on for that LUN. 84130f4520SKenneth D. Merry */ 85130f4520SKenneth D. Merry if ((lun != NULL) 86130f4520SKenneth D. Merry && (lun->flags & CTL_LUN_SENSE_DESC)) 87130f4520SKenneth D. Merry sense_format = SSD_TYPE_DESC; 88130f4520SKenneth D. Merry else 89130f4520SKenneth D. Merry sense_format = SSD_TYPE_FIXED; 90130f4520SKenneth D. Merry } 91130f4520SKenneth D. Merry 92130f4520SKenneth D. Merry scsi_set_sense_data_va(sense_data, sense_format, current_error, 93130f4520SKenneth D. Merry sense_key, asc, ascq, ap); 94130f4520SKenneth D. Merry } 95130f4520SKenneth D. Merry 96130f4520SKenneth D. Merry void 97130f4520SKenneth D. Merry ctl_set_sense_data(struct scsi_sense_data *sense_data, void *lunptr, 98130f4520SKenneth D. Merry scsi_sense_data_type sense_format, int current_error, 99130f4520SKenneth D. Merry int sense_key, int asc, int ascq, ...) 100130f4520SKenneth D. Merry { 101130f4520SKenneth D. Merry va_list ap; 102130f4520SKenneth D. Merry 103130f4520SKenneth D. Merry va_start(ap, ascq); 104130f4520SKenneth D. Merry ctl_set_sense_data_va(sense_data, lunptr, sense_format, current_error, 105130f4520SKenneth D. Merry sense_key, asc, ascq, ap); 106130f4520SKenneth D. Merry va_end(ap); 107130f4520SKenneth D. Merry } 108130f4520SKenneth D. Merry 109130f4520SKenneth D. Merry void 110130f4520SKenneth D. Merry ctl_set_sense(struct ctl_scsiio *ctsio, int current_error, int sense_key, 111130f4520SKenneth D. Merry int asc, int ascq, ...) 112130f4520SKenneth D. Merry { 113130f4520SKenneth D. Merry va_list ap; 114130f4520SKenneth D. Merry struct ctl_lun *lun; 115130f4520SKenneth D. Merry 116130f4520SKenneth D. Merry /* 117130f4520SKenneth D. Merry * The LUN can't go away until all of the commands have been 118130f4520SKenneth D. Merry * completed. Therefore we can safely access the LUN structure and 119130f4520SKenneth D. Merry * flags without the lock. 120130f4520SKenneth D. Merry */ 121130f4520SKenneth D. Merry lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; 122130f4520SKenneth D. Merry 123130f4520SKenneth D. Merry va_start(ap, ascq); 124130f4520SKenneth D. Merry ctl_set_sense_data_va(&ctsio->sense_data, 125130f4520SKenneth D. Merry lun, 126130f4520SKenneth D. Merry SSD_TYPE_NONE, 127130f4520SKenneth D. Merry current_error, 128130f4520SKenneth D. Merry sense_key, 129130f4520SKenneth D. Merry asc, 130130f4520SKenneth D. Merry ascq, 131130f4520SKenneth D. Merry ap); 132130f4520SKenneth D. Merry va_end(ap); 133130f4520SKenneth D. Merry 134130f4520SKenneth D. Merry ctsio->scsi_status = SCSI_STATUS_CHECK_COND; 135130f4520SKenneth D. Merry ctsio->sense_len = SSD_FULL_SIZE; 136130f4520SKenneth D. Merry ctsio->io_hdr.status = CTL_SCSI_ERROR | CTL_AUTOSENSE; 137130f4520SKenneth D. Merry } 138130f4520SKenneth D. Merry 139130f4520SKenneth D. Merry /* 140130f4520SKenneth D. Merry * Transform fixed sense data into descriptor sense data. 141130f4520SKenneth D. Merry * 142130f4520SKenneth D. Merry * For simplicity's sake, we assume that both sense structures are 143130f4520SKenneth D. Merry * SSD_FULL_SIZE. Otherwise, the logic gets more complicated. 144130f4520SKenneth D. Merry */ 145130f4520SKenneth D. Merry void 146130f4520SKenneth D. Merry ctl_sense_to_desc(struct scsi_sense_data_fixed *sense_src, 147130f4520SKenneth D. Merry struct scsi_sense_data_desc *sense_dest) 148130f4520SKenneth D. Merry { 149130f4520SKenneth D. Merry struct scsi_sense_stream stream_sense; 150130f4520SKenneth D. Merry int current_error; 151130f4520SKenneth D. Merry uint8_t stream_bits; 152130f4520SKenneth D. Merry 153130f4520SKenneth D. Merry bzero(sense_dest, sizeof(*sense_dest)); 154130f4520SKenneth D. Merry 155130f4520SKenneth D. Merry if ((sense_src->error_code & SSD_ERRCODE) == SSD_DEFERRED_ERROR) 156130f4520SKenneth D. Merry current_error = 0; 157130f4520SKenneth D. Merry else 158130f4520SKenneth D. Merry current_error = 1; 159130f4520SKenneth D. Merry 160130f4520SKenneth D. Merry bzero(&stream_sense, sizeof(stream_sense)); 161130f4520SKenneth D. Merry 162130f4520SKenneth D. Merry /* 163130f4520SKenneth D. Merry * Check to see whether any of the tape-specific bits are set. If 164130f4520SKenneth D. Merry * so, we'll need a stream sense descriptor. 165130f4520SKenneth D. Merry */ 166130f4520SKenneth D. Merry if (sense_src->flags & (SSD_ILI|SSD_EOM|SSD_FILEMARK)) 167130f4520SKenneth D. Merry stream_bits = sense_src->flags & ~SSD_KEY; 168130f4520SKenneth D. Merry else 169130f4520SKenneth D. Merry stream_bits = 0; 170130f4520SKenneth D. Merry 171130f4520SKenneth D. Merry /* 172130f4520SKenneth D. Merry * Utilize our sense setting routine to do the transform. If a 173130f4520SKenneth D. Merry * value is set in the fixed sense data, set it in the descriptor 174130f4520SKenneth D. Merry * data. Otherwise, skip it. 175130f4520SKenneth D. Merry */ 176130f4520SKenneth D. Merry ctl_set_sense_data((struct scsi_sense_data *)sense_dest, 177130f4520SKenneth D. Merry /*lun*/ NULL, 178130f4520SKenneth D. Merry /*sense_format*/ SSD_TYPE_DESC, 179130f4520SKenneth D. Merry current_error, 180130f4520SKenneth D. Merry /*sense_key*/ sense_src->flags & SSD_KEY, 181130f4520SKenneth D. Merry /*asc*/ sense_src->add_sense_code, 182130f4520SKenneth D. Merry /*ascq*/ sense_src->add_sense_code_qual, 183130f4520SKenneth D. Merry 184130f4520SKenneth D. Merry /* Information Bytes */ 185130f4520SKenneth D. Merry (scsi_4btoul(sense_src->info) != 0) ? 186130f4520SKenneth D. Merry SSD_ELEM_INFO : SSD_ELEM_SKIP, 187130f4520SKenneth D. Merry sizeof(sense_src->info), 188130f4520SKenneth D. Merry sense_src->info, 189130f4520SKenneth D. Merry 190130f4520SKenneth D. Merry /* Command specific bytes */ 191130f4520SKenneth D. Merry (scsi_4btoul(sense_src->cmd_spec_info) != 0) ? 192130f4520SKenneth D. Merry SSD_ELEM_COMMAND : SSD_ELEM_SKIP, 193130f4520SKenneth D. Merry sizeof(sense_src->cmd_spec_info), 194130f4520SKenneth D. Merry sense_src->cmd_spec_info, 195130f4520SKenneth D. Merry 196130f4520SKenneth D. Merry /* FRU */ 197130f4520SKenneth D. Merry (sense_src->fru != 0) ? 198130f4520SKenneth D. Merry SSD_ELEM_FRU : SSD_ELEM_SKIP, 199130f4520SKenneth D. Merry sizeof(sense_src->fru), 200130f4520SKenneth D. Merry &sense_src->fru, 201130f4520SKenneth D. Merry 202130f4520SKenneth D. Merry /* Sense Key Specific */ 203130f4520SKenneth D. Merry (sense_src->sense_key_spec[0] & SSD_SCS_VALID) ? 204130f4520SKenneth D. Merry SSD_ELEM_SKS : SSD_ELEM_SKIP, 205130f4520SKenneth D. Merry sizeof(sense_src->sense_key_spec), 206130f4520SKenneth D. Merry sense_src->sense_key_spec, 207130f4520SKenneth D. Merry 208130f4520SKenneth D. Merry /* Tape bits */ 209130f4520SKenneth D. Merry (stream_bits != 0) ? 210130f4520SKenneth D. Merry SSD_ELEM_STREAM : SSD_ELEM_SKIP, 211130f4520SKenneth D. Merry sizeof(stream_bits), 212130f4520SKenneth D. Merry &stream_bits, 213130f4520SKenneth D. Merry 214130f4520SKenneth D. Merry SSD_ELEM_NONE); 215130f4520SKenneth D. Merry } 216130f4520SKenneth D. Merry 217130f4520SKenneth D. Merry /* 218130f4520SKenneth D. Merry * Transform descriptor format sense data into fixed sense data. 219130f4520SKenneth D. Merry * 220130f4520SKenneth D. Merry * Some data may be lost in translation, because there are descriptors 221130f4520SKenneth D. Merry * thant can't be represented as fixed sense data. 222130f4520SKenneth D. Merry * 223130f4520SKenneth D. Merry * For simplicity's sake, we assume that both sense structures are 224130f4520SKenneth D. Merry * SSD_FULL_SIZE. Otherwise, the logic gets more complicated. 225130f4520SKenneth D. Merry */ 226130f4520SKenneth D. Merry void 227130f4520SKenneth D. Merry ctl_sense_to_fixed(struct scsi_sense_data_desc *sense_src, 228130f4520SKenneth D. Merry struct scsi_sense_data_fixed *sense_dest) 229130f4520SKenneth D. Merry { 230130f4520SKenneth D. Merry int current_error; 231130f4520SKenneth D. Merry uint8_t *info_ptr = NULL, *cmd_ptr = NULL, *fru_ptr = NULL; 232130f4520SKenneth D. Merry uint8_t *sks_ptr = NULL, *stream_ptr = NULL; 233130f4520SKenneth D. Merry int info_size = 0, cmd_size = 0, fru_size = 0; 234130f4520SKenneth D. Merry int sks_size = 0, stream_size = 0; 235130f4520SKenneth D. Merry int pos; 236130f4520SKenneth D. Merry 237130f4520SKenneth D. Merry if ((sense_src->error_code & SSD_ERRCODE) == SSD_DESC_CURRENT_ERROR) 238130f4520SKenneth D. Merry current_error = 1; 239130f4520SKenneth D. Merry else 240130f4520SKenneth D. Merry current_error = 0; 241130f4520SKenneth D. Merry 242130f4520SKenneth D. Merry for (pos = 0; pos < (int)(sense_src->extra_len - 1);) { 243130f4520SKenneth D. Merry struct scsi_sense_desc_header *header; 244130f4520SKenneth D. Merry 245130f4520SKenneth D. Merry header = (struct scsi_sense_desc_header *) 246130f4520SKenneth D. Merry &sense_src->sense_desc[pos]; 247130f4520SKenneth D. Merry 248130f4520SKenneth D. Merry /* 249130f4520SKenneth D. Merry * See if this record goes past the end of the sense data. 250130f4520SKenneth D. Merry * It shouldn't, but check just in case. 251130f4520SKenneth D. Merry */ 252130f4520SKenneth D. Merry if ((pos + header->length + sizeof(*header)) > 253130f4520SKenneth D. Merry sense_src->extra_len) 254130f4520SKenneth D. Merry break; 255130f4520SKenneth D. Merry 256130f4520SKenneth D. Merry switch (sense_src->sense_desc[pos]) { 257130f4520SKenneth D. Merry case SSD_DESC_INFO: { 258130f4520SKenneth D. Merry struct scsi_sense_info *info; 259130f4520SKenneth D. Merry 260130f4520SKenneth D. Merry info = (struct scsi_sense_info *)header; 261130f4520SKenneth D. Merry 262130f4520SKenneth D. Merry info_ptr = info->info; 263130f4520SKenneth D. Merry info_size = sizeof(info->info); 264130f4520SKenneth D. Merry 265130f4520SKenneth D. Merry pos += info->length + 266130f4520SKenneth D. Merry sizeof(struct scsi_sense_desc_header); 267130f4520SKenneth D. Merry break; 268130f4520SKenneth D. Merry } 269130f4520SKenneth D. Merry case SSD_DESC_COMMAND: { 270130f4520SKenneth D. Merry struct scsi_sense_command *cmd; 271130f4520SKenneth D. Merry 272130f4520SKenneth D. Merry cmd = (struct scsi_sense_command *)header; 273130f4520SKenneth D. Merry cmd_ptr = cmd->command_info; 274130f4520SKenneth D. Merry cmd_size = sizeof(cmd->command_info); 275130f4520SKenneth D. Merry 276130f4520SKenneth D. Merry pos += cmd->length + 277130f4520SKenneth D. Merry sizeof(struct scsi_sense_desc_header); 278130f4520SKenneth D. Merry break; 279130f4520SKenneth D. Merry } 280130f4520SKenneth D. Merry case SSD_DESC_FRU: { 281130f4520SKenneth D. Merry struct scsi_sense_fru *fru; 282130f4520SKenneth D. Merry 283130f4520SKenneth D. Merry fru = (struct scsi_sense_fru *)header; 284130f4520SKenneth D. Merry fru_ptr = &fru->fru; 285130f4520SKenneth D. Merry fru_size = sizeof(fru->fru); 286130f4520SKenneth D. Merry pos += fru->length + 287130f4520SKenneth D. Merry sizeof(struct scsi_sense_desc_header); 288130f4520SKenneth D. Merry break; 289130f4520SKenneth D. Merry } 290130f4520SKenneth D. Merry case SSD_DESC_SKS: { 291130f4520SKenneth D. Merry struct scsi_sense_sks *sks; 292130f4520SKenneth D. Merry 293130f4520SKenneth D. Merry sks = (struct scsi_sense_sks *)header; 294130f4520SKenneth D. Merry sks_ptr = sks->sense_key_spec; 295130f4520SKenneth D. Merry sks_size = sizeof(sks->sense_key_spec); 296130f4520SKenneth D. Merry 297130f4520SKenneth D. Merry pos = sks->length + 298130f4520SKenneth D. Merry sizeof(struct scsi_sense_desc_header); 299130f4520SKenneth D. Merry break; 300130f4520SKenneth D. Merry } 301130f4520SKenneth D. Merry case SSD_DESC_STREAM: { 302130f4520SKenneth D. Merry struct scsi_sense_stream *stream_sense; 303130f4520SKenneth D. Merry 304130f4520SKenneth D. Merry stream_sense = (struct scsi_sense_stream *)header; 305130f4520SKenneth D. Merry stream_ptr = &stream_sense->byte3; 306130f4520SKenneth D. Merry stream_size = sizeof(stream_sense->byte3); 307130f4520SKenneth D. Merry pos = stream_sense->length + 308130f4520SKenneth D. Merry sizeof(struct scsi_sense_desc_header); 309130f4520SKenneth D. Merry break; 310130f4520SKenneth D. Merry } 311130f4520SKenneth D. Merry default: 312130f4520SKenneth D. Merry /* 313130f4520SKenneth D. Merry * We don't recognize this particular sense 314130f4520SKenneth D. Merry * descriptor type, so just skip it. 315130f4520SKenneth D. Merry */ 316130f4520SKenneth D. Merry pos += sizeof(*header) + header->length; 317130f4520SKenneth D. Merry break; 318130f4520SKenneth D. Merry } 319130f4520SKenneth D. Merry } 320130f4520SKenneth D. Merry 321130f4520SKenneth D. Merry ctl_set_sense_data((struct scsi_sense_data *)sense_dest, 322130f4520SKenneth D. Merry /*lun*/ NULL, 323130f4520SKenneth D. Merry /*sense_format*/ SSD_TYPE_FIXED, 324130f4520SKenneth D. Merry current_error, 325130f4520SKenneth D. Merry /*sense_key*/ sense_src->sense_key & SSD_KEY, 326130f4520SKenneth D. Merry /*asc*/ sense_src->add_sense_code, 327130f4520SKenneth D. Merry /*ascq*/ sense_src->add_sense_code_qual, 328130f4520SKenneth D. Merry 329130f4520SKenneth D. Merry /* Information Bytes */ 330130f4520SKenneth D. Merry (info_ptr != NULL) ? SSD_ELEM_INFO : SSD_ELEM_SKIP, 331130f4520SKenneth D. Merry info_size, 332130f4520SKenneth D. Merry info_ptr, 333130f4520SKenneth D. Merry 334130f4520SKenneth D. Merry /* Command specific bytes */ 335130f4520SKenneth D. Merry (cmd_ptr != NULL) ? SSD_ELEM_COMMAND : SSD_ELEM_SKIP, 336130f4520SKenneth D. Merry cmd_size, 337130f4520SKenneth D. Merry cmd_ptr, 338130f4520SKenneth D. Merry 339130f4520SKenneth D. Merry /* FRU */ 340130f4520SKenneth D. Merry (fru_ptr != NULL) ? SSD_ELEM_FRU : SSD_ELEM_SKIP, 341130f4520SKenneth D. Merry fru_size, 342130f4520SKenneth D. Merry fru_ptr, 343130f4520SKenneth D. Merry 344130f4520SKenneth D. Merry /* Sense Key Specific */ 345130f4520SKenneth D. Merry (sks_ptr != NULL) ? SSD_ELEM_SKS : SSD_ELEM_SKIP, 346130f4520SKenneth D. Merry sks_size, 347130f4520SKenneth D. Merry sks_ptr, 348130f4520SKenneth D. Merry 349130f4520SKenneth D. Merry /* Tape bits */ 350130f4520SKenneth D. Merry (stream_ptr != NULL) ? SSD_ELEM_STREAM : SSD_ELEM_SKIP, 351130f4520SKenneth D. Merry stream_size, 352130f4520SKenneth D. Merry stream_ptr, 353130f4520SKenneth D. Merry 354130f4520SKenneth D. Merry SSD_ELEM_NONE); 355130f4520SKenneth D. Merry } 356130f4520SKenneth D. Merry 357130f4520SKenneth D. Merry void 358130f4520SKenneth D. Merry ctl_set_ua(struct ctl_scsiio *ctsio, int asc, int ascq) 359130f4520SKenneth D. Merry { 360130f4520SKenneth D. Merry ctl_set_sense(ctsio, 361130f4520SKenneth D. Merry /*current_error*/ 1, 362130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_UNIT_ATTENTION, 363130f4520SKenneth D. Merry asc, 364130f4520SKenneth D. Merry ascq, 365130f4520SKenneth D. Merry SSD_ELEM_NONE); 366130f4520SKenneth D. Merry } 367130f4520SKenneth D. Merry 368130f4520SKenneth D. Merry ctl_ua_type 3699e525653SAlexander Motin ctl_build_ua(struct ctl_lun *lun, uint32_t initidx, 3709e525653SAlexander Motin struct scsi_sense_data *sense, scsi_sense_data_type sense_format) 371130f4520SKenneth D. Merry { 3729e525653SAlexander Motin ctl_ua_type *ua; 3738f07b2d5SAlexander Motin ctl_ua_type ua_to_build, ua_to_clear; 3748f07b2d5SAlexander Motin int asc, ascq; 3759e525653SAlexander Motin uint32_t p, i; 376130f4520SKenneth D. Merry 3779e525653SAlexander Motin mtx_assert(&lun->lun_lock, MA_OWNED); 3789e525653SAlexander Motin p = initidx / CTL_MAX_INIT_PER_PORT; 3799e525653SAlexander Motin if ((ua = lun->pending_ua[p]) == NULL) { 3809e525653SAlexander Motin mtx_unlock(&lun->lun_lock); 3819e525653SAlexander Motin ua = malloc(sizeof(ctl_ua_type) * CTL_MAX_INIT_PER_PORT, 3829e525653SAlexander Motin M_CTL, M_WAITOK); 3839e525653SAlexander Motin mtx_lock(&lun->lun_lock); 3849e525653SAlexander Motin if (lun->pending_ua[p] == NULL) { 3859e525653SAlexander Motin lun->pending_ua[p] = ua; 3869e525653SAlexander Motin for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) 3879e525653SAlexander Motin ua[i] = CTL_UA_POWERON; 3889e525653SAlexander Motin } else { 3899e525653SAlexander Motin free(ua, M_CTL); 3909e525653SAlexander Motin ua = lun->pending_ua[p]; 3919e525653SAlexander Motin } 3929e525653SAlexander Motin } 3939e525653SAlexander Motin i = initidx % CTL_MAX_INIT_PER_PORT; 3949e525653SAlexander Motin if (ua[i] == CTL_UA_NONE) 3958f07b2d5SAlexander Motin return (CTL_UA_NONE); 396130f4520SKenneth D. Merry 3979e525653SAlexander Motin ua_to_build = (1 << (ffs(ua[i]) - 1)); 3988f07b2d5SAlexander Motin ua_to_clear = ua_to_build; 399130f4520SKenneth D. Merry 400130f4520SKenneth D. Merry switch (ua_to_build) { 401130f4520SKenneth D. Merry case CTL_UA_POWERON: 402130f4520SKenneth D. Merry /* 29h/01h POWER ON OCCURRED */ 403130f4520SKenneth D. Merry asc = 0x29; 404130f4520SKenneth D. Merry ascq = 0x01; 4058f07b2d5SAlexander Motin ua_to_clear = ~0; 406130f4520SKenneth D. Merry break; 407130f4520SKenneth D. Merry case CTL_UA_BUS_RESET: 408130f4520SKenneth D. Merry /* 29h/02h SCSI BUS RESET OCCURRED */ 409130f4520SKenneth D. Merry asc = 0x29; 410130f4520SKenneth D. Merry ascq = 0x02; 4118f07b2d5SAlexander Motin ua_to_clear = ~0; 412130f4520SKenneth D. Merry break; 413130f4520SKenneth D. Merry case CTL_UA_TARG_RESET: 414130f4520SKenneth D. Merry /* 29h/03h BUS DEVICE RESET FUNCTION OCCURRED*/ 415130f4520SKenneth D. Merry asc = 0x29; 416130f4520SKenneth D. Merry ascq = 0x03; 4178f07b2d5SAlexander Motin ua_to_clear = ~0; 418130f4520SKenneth D. Merry break; 4190020682bSAlexander Motin case CTL_UA_I_T_NEXUS_LOSS: 4200020682bSAlexander Motin /* 29h/07h I_T NEXUS LOSS OCCURRED */ 4210020682bSAlexander Motin asc = 0x29; 4220020682bSAlexander Motin ascq = 0x07; 4238f07b2d5SAlexander Motin ua_to_clear = ~0; 4240020682bSAlexander Motin break; 425130f4520SKenneth D. Merry case CTL_UA_LUN_RESET: 426130f4520SKenneth D. Merry /* 29h/00h POWER ON, RESET, OR BUS DEVICE RESET OCCURRED */ 427130f4520SKenneth D. Merry /* 428130f4520SKenneth D. Merry * Since we don't have a specific ASC/ASCQ pair for a LUN 429130f4520SKenneth D. Merry * reset, just return the generic reset code. 430130f4520SKenneth D. Merry */ 431130f4520SKenneth D. Merry asc = 0x29; 432130f4520SKenneth D. Merry ascq = 0x00; 433130f4520SKenneth D. Merry break; 434130f4520SKenneth D. Merry case CTL_UA_LUN_CHANGE: 435130f4520SKenneth D. Merry /* 3Fh/0Eh REPORTED LUNS DATA HAS CHANGED */ 436130f4520SKenneth D. Merry asc = 0x3F; 437130f4520SKenneth D. Merry ascq = 0x0E; 438130f4520SKenneth D. Merry break; 439130f4520SKenneth D. Merry case CTL_UA_MODE_CHANGE: 440130f4520SKenneth D. Merry /* 2Ah/01h MODE PARAMETERS CHANGED */ 441130f4520SKenneth D. Merry asc = 0x2A; 442130f4520SKenneth D. Merry ascq = 0x01; 443130f4520SKenneth D. Merry break; 444130f4520SKenneth D. Merry case CTL_UA_LOG_CHANGE: 445130f4520SKenneth D. Merry /* 2Ah/02h LOG PARAMETERS CHANGED */ 446130f4520SKenneth D. Merry asc = 0x2A; 447130f4520SKenneth D. Merry ascq = 0x02; 448130f4520SKenneth D. Merry break; 449130f4520SKenneth D. Merry case CTL_UA_RES_PREEMPT: 450130f4520SKenneth D. Merry /* 2Ah/03h RESERVATIONS PREEMPTED */ 451130f4520SKenneth D. Merry asc = 0x2A; 452130f4520SKenneth D. Merry ascq = 0x03; 453130f4520SKenneth D. Merry break; 454130f4520SKenneth D. Merry case CTL_UA_RES_RELEASE: 455130f4520SKenneth D. Merry /* 2Ah/04h RESERVATIONS RELEASED */ 456130f4520SKenneth D. Merry asc = 0x2A; 457130f4520SKenneth D. Merry ascq = 0x04; 458130f4520SKenneth D. Merry break; 459130f4520SKenneth D. Merry case CTL_UA_REG_PREEMPT: 460130f4520SKenneth D. Merry /* 2Ah/05h REGISTRATIONS PREEMPTED */ 461130f4520SKenneth D. Merry asc = 0x2A; 462130f4520SKenneth D. Merry ascq = 0x05; 463130f4520SKenneth D. Merry break; 464130f4520SKenneth D. Merry case CTL_UA_ASYM_ACC_CHANGE: 465130f4520SKenneth D. Merry /* 2Ah/06n ASYMMETRIC ACCESS STATE CHANGED */ 466130f4520SKenneth D. Merry asc = 0x2A; 467130f4520SKenneth D. Merry ascq = 0x06; 468130f4520SKenneth D. Merry break; 46981177295SEdward Tomasz Napierala case CTL_UA_CAPACITY_CHANGED: 47081177295SEdward Tomasz Napierala /* 2Ah/09n CAPACITY DATA HAS CHANGED */ 47181177295SEdward Tomasz Napierala asc = 0x2A; 47281177295SEdward Tomasz Napierala ascq = 0x09; 47381177295SEdward Tomasz Napierala break; 474c3e7ba3eSAlexander Motin case CTL_UA_THIN_PROV_THRES: 475c3e7ba3eSAlexander Motin /* 38h/07n THIN PROVISIONING SOFT THRESHOLD REACHED */ 476c3e7ba3eSAlexander Motin asc = 0x38; 477c3e7ba3eSAlexander Motin ascq = 0x07; 478c3e7ba3eSAlexander Motin break; 479130f4520SKenneth D. Merry default: 4808f07b2d5SAlexander Motin panic("ctl_build_ua: Unknown UA %x", ua_to_build); 481130f4520SKenneth D. Merry } 482130f4520SKenneth D. Merry 483130f4520SKenneth D. Merry ctl_set_sense_data(sense, 484130f4520SKenneth D. Merry /*lun*/ NULL, 485130f4520SKenneth D. Merry sense_format, 486130f4520SKenneth D. Merry /*current_error*/ 1, 487130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_UNIT_ATTENTION, 488130f4520SKenneth D. Merry asc, 489130f4520SKenneth D. Merry ascq, 490130f4520SKenneth D. Merry SSD_ELEM_NONE); 491130f4520SKenneth D. Merry 4928f07b2d5SAlexander Motin /* We're reporting this UA, so clear it */ 4939e525653SAlexander Motin ua[i] &= ~ua_to_clear; 4948f07b2d5SAlexander Motin 495130f4520SKenneth D. Merry return (ua_to_build); 496130f4520SKenneth D. Merry } 497130f4520SKenneth D. Merry 498130f4520SKenneth D. Merry void 499130f4520SKenneth D. Merry ctl_set_overlapped_cmd(struct ctl_scsiio *ctsio) 500130f4520SKenneth D. Merry { 501130f4520SKenneth D. Merry /* OVERLAPPED COMMANDS ATTEMPTED */ 502130f4520SKenneth D. Merry ctl_set_sense(ctsio, 503130f4520SKenneth D. Merry /*current_error*/ 1, 504130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 505130f4520SKenneth D. Merry /*asc*/ 0x4E, 506130f4520SKenneth D. Merry /*ascq*/ 0x00, 507130f4520SKenneth D. Merry SSD_ELEM_NONE); 508130f4520SKenneth D. Merry } 509130f4520SKenneth D. Merry 510130f4520SKenneth D. Merry void 511130f4520SKenneth D. Merry ctl_set_overlapped_tag(struct ctl_scsiio *ctsio, uint8_t tag) 512130f4520SKenneth D. Merry { 513130f4520SKenneth D. Merry /* TAGGED OVERLAPPED COMMANDS (NN = QUEUE TAG) */ 514130f4520SKenneth D. Merry ctl_set_sense(ctsio, 515130f4520SKenneth D. Merry /*current_error*/ 1, 516130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 517130f4520SKenneth D. Merry /*asc*/ 0x4D, 518130f4520SKenneth D. Merry /*ascq*/ tag, 519130f4520SKenneth D. Merry SSD_ELEM_NONE); 520130f4520SKenneth D. Merry } 521130f4520SKenneth D. Merry 522130f4520SKenneth D. Merry /* 523130f4520SKenneth D. Merry * Tell the user that there was a problem with the command or data he sent. 524130f4520SKenneth D. Merry */ 525130f4520SKenneth D. Merry void 526130f4520SKenneth D. Merry ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command, 527130f4520SKenneth D. Merry int field, int bit_valid, int bit) 528130f4520SKenneth D. Merry { 529130f4520SKenneth D. Merry uint8_t sks[3]; 530130f4520SKenneth D. Merry int asc; 531130f4520SKenneth D. Merry 532130f4520SKenneth D. Merry if (command != 0) { 533130f4520SKenneth D. Merry /* "Invalid field in CDB" */ 534130f4520SKenneth D. Merry asc = 0x24; 535130f4520SKenneth D. Merry } else { 536130f4520SKenneth D. Merry /* "Invalid field in parameter list" */ 537130f4520SKenneth D. Merry asc = 0x26; 538130f4520SKenneth D. Merry } 539130f4520SKenneth D. Merry 540130f4520SKenneth D. Merry if (sks_valid) { 541130f4520SKenneth D. Merry sks[0] = SSD_SCS_VALID; 542130f4520SKenneth D. Merry if (command) 543130f4520SKenneth D. Merry sks[0] |= SSD_FIELDPTR_CMD; 544130f4520SKenneth D. Merry scsi_ulto2b(field, &sks[1]); 545130f4520SKenneth D. Merry 546130f4520SKenneth D. Merry if (bit_valid) 547130f4520SKenneth D. Merry sks[0] |= SSD_BITPTR_VALID | bit; 548130f4520SKenneth D. Merry } 549130f4520SKenneth D. Merry 550130f4520SKenneth D. Merry ctl_set_sense(ctsio, 551130f4520SKenneth D. Merry /*current_error*/ 1, 552130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 553130f4520SKenneth D. Merry asc, 554130f4520SKenneth D. Merry /*ascq*/ 0x00, 555130f4520SKenneth D. Merry /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP, 556130f4520SKenneth D. Merry /*size*/ sizeof(sks), 557130f4520SKenneth D. Merry /*data*/ sks, 558130f4520SKenneth D. Merry SSD_ELEM_NONE); 559130f4520SKenneth D. Merry } 560130f4520SKenneth D. Merry 561130f4520SKenneth D. Merry void 562130f4520SKenneth D. Merry ctl_set_invalid_opcode(struct ctl_scsiio *ctsio) 563130f4520SKenneth D. Merry { 564130f4520SKenneth D. Merry struct scsi_sense_data *sense; 565130f4520SKenneth D. Merry uint8_t sks[3]; 566130f4520SKenneth D. Merry 567130f4520SKenneth D. Merry sense = &ctsio->sense_data; 568130f4520SKenneth D. Merry 569130f4520SKenneth D. Merry sks[0] = SSD_SCS_VALID | SSD_FIELDPTR_CMD; 570130f4520SKenneth D. Merry scsi_ulto2b(0, &sks[1]); 571130f4520SKenneth D. Merry 572130f4520SKenneth D. Merry /* "Invalid command operation code" */ 573130f4520SKenneth D. Merry ctl_set_sense(ctsio, 574130f4520SKenneth D. Merry /*current_error*/ 1, 575130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 576130f4520SKenneth D. Merry /*asc*/ 0x20, 577130f4520SKenneth D. Merry /*ascq*/ 0x00, 578130f4520SKenneth D. Merry /*type*/ SSD_ELEM_SKS, 579130f4520SKenneth D. Merry /*size*/ sizeof(sks), 580130f4520SKenneth D. Merry /*data*/ sks, 581130f4520SKenneth D. Merry SSD_ELEM_NONE); 582130f4520SKenneth D. Merry } 583130f4520SKenneth D. Merry 584130f4520SKenneth D. Merry void 585130f4520SKenneth D. Merry ctl_set_param_len_error(struct ctl_scsiio *ctsio) 586130f4520SKenneth D. Merry { 587130f4520SKenneth D. Merry /* "Parameter list length error" */ 588130f4520SKenneth D. Merry ctl_set_sense(ctsio, 589130f4520SKenneth D. Merry /*current_error*/ 1, 590130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 591130f4520SKenneth D. Merry /*asc*/ 0x1a, 592130f4520SKenneth D. Merry /*ascq*/ 0x00, 593130f4520SKenneth D. Merry SSD_ELEM_NONE); 594130f4520SKenneth D. Merry } 595130f4520SKenneth D. Merry 596130f4520SKenneth D. Merry void 597130f4520SKenneth D. Merry ctl_set_already_locked(struct ctl_scsiio *ctsio) 598130f4520SKenneth D. Merry { 599130f4520SKenneth D. Merry /* Vendor unique "Somebody already is locked" */ 600130f4520SKenneth D. Merry ctl_set_sense(ctsio, 601130f4520SKenneth D. Merry /*current_error*/ 1, 602130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 603130f4520SKenneth D. Merry /*asc*/ 0x81, 604130f4520SKenneth D. Merry /*ascq*/ 0x00, 605130f4520SKenneth D. Merry SSD_ELEM_NONE); 606130f4520SKenneth D. Merry } 607130f4520SKenneth D. Merry 608130f4520SKenneth D. Merry void 609130f4520SKenneth D. Merry ctl_set_unsupported_lun(struct ctl_scsiio *ctsio) 610130f4520SKenneth D. Merry { 611130f4520SKenneth D. Merry /* "Logical unit not supported" */ 612130f4520SKenneth D. Merry ctl_set_sense(ctsio, 613130f4520SKenneth D. Merry /*current_error*/ 1, 614130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 615130f4520SKenneth D. Merry /*asc*/ 0x25, 616130f4520SKenneth D. Merry /*ascq*/ 0x00, 617130f4520SKenneth D. Merry SSD_ELEM_NONE); 618130f4520SKenneth D. Merry } 619130f4520SKenneth D. Merry 620130f4520SKenneth D. Merry void 621130f4520SKenneth D. Merry ctl_set_internal_failure(struct ctl_scsiio *ctsio, int sks_valid, 622130f4520SKenneth D. Merry uint16_t retry_count) 623130f4520SKenneth D. Merry { 624130f4520SKenneth D. Merry uint8_t sks[3]; 625130f4520SKenneth D. Merry 626130f4520SKenneth D. Merry if (sks_valid) { 627130f4520SKenneth D. Merry sks[0] = SSD_SCS_VALID; 628130f4520SKenneth D. Merry sks[1] = (retry_count >> 8) & 0xff; 629130f4520SKenneth D. Merry sks[2] = retry_count & 0xff; 630130f4520SKenneth D. Merry } 631130f4520SKenneth D. Merry 632130f4520SKenneth D. Merry /* "Internal target failure" */ 633130f4520SKenneth D. Merry ctl_set_sense(ctsio, 634130f4520SKenneth D. Merry /*current_error*/ 1, 635130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_HARDWARE_ERROR, 636130f4520SKenneth D. Merry /*asc*/ 0x44, 637130f4520SKenneth D. Merry /*ascq*/ 0x00, 638130f4520SKenneth D. Merry /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP, 639130f4520SKenneth D. Merry /*size*/ sizeof(sks), 640130f4520SKenneth D. Merry /*data*/ sks, 641130f4520SKenneth D. Merry SSD_ELEM_NONE); 642130f4520SKenneth D. Merry } 643130f4520SKenneth D. Merry 644130f4520SKenneth D. Merry void 645130f4520SKenneth D. Merry ctl_set_medium_error(struct ctl_scsiio *ctsio) 646130f4520SKenneth D. Merry { 647130f4520SKenneth D. Merry if ((ctsio->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) { 648130f4520SKenneth D. Merry /* "Unrecovered read error" */ 649130f4520SKenneth D. Merry ctl_set_sense(ctsio, 650130f4520SKenneth D. Merry /*current_error*/ 1, 651130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_MEDIUM_ERROR, 652130f4520SKenneth D. Merry /*asc*/ 0x11, 653130f4520SKenneth D. Merry /*ascq*/ 0x00, 654130f4520SKenneth D. Merry SSD_ELEM_NONE); 655130f4520SKenneth D. Merry } else { 656130f4520SKenneth D. Merry /* "Write error - auto reallocation failed" */ 657130f4520SKenneth D. Merry ctl_set_sense(ctsio, 658130f4520SKenneth D. Merry /*current_error*/ 1, 659130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_MEDIUM_ERROR, 660130f4520SKenneth D. Merry /*asc*/ 0x0C, 661130f4520SKenneth D. Merry /*ascq*/ 0x02, 662130f4520SKenneth D. Merry SSD_ELEM_NONE); 663130f4520SKenneth D. Merry } 664130f4520SKenneth D. Merry } 665130f4520SKenneth D. Merry 666130f4520SKenneth D. Merry void 667130f4520SKenneth D. Merry ctl_set_aborted(struct ctl_scsiio *ctsio) 668130f4520SKenneth D. Merry { 669130f4520SKenneth D. Merry ctl_set_sense(ctsio, 670130f4520SKenneth D. Merry /*current_error*/ 1, 671130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ABORTED_COMMAND, 672130f4520SKenneth D. Merry /*asc*/ 0x45, 673130f4520SKenneth D. Merry /*ascq*/ 0x00, 674130f4520SKenneth D. Merry SSD_ELEM_NONE); 675130f4520SKenneth D. Merry } 676130f4520SKenneth D. Merry 677130f4520SKenneth D. Merry void 678130f4520SKenneth D. Merry ctl_set_lba_out_of_range(struct ctl_scsiio *ctsio) 679130f4520SKenneth D. Merry { 680130f4520SKenneth D. Merry /* "Logical block address out of range" */ 681130f4520SKenneth D. Merry ctl_set_sense(ctsio, 682130f4520SKenneth D. Merry /*current_error*/ 1, 683130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 684130f4520SKenneth D. Merry /*asc*/ 0x21, 685130f4520SKenneth D. Merry /*ascq*/ 0x00, 686130f4520SKenneth D. Merry SSD_ELEM_NONE); 687130f4520SKenneth D. Merry } 688130f4520SKenneth D. Merry 689130f4520SKenneth D. Merry void 690130f4520SKenneth D. Merry ctl_set_lun_stopped(struct ctl_scsiio *ctsio) 691130f4520SKenneth D. Merry { 692130f4520SKenneth D. Merry /* "Logical unit not ready, initializing cmd. required" */ 693130f4520SKenneth D. Merry ctl_set_sense(ctsio, 694130f4520SKenneth D. Merry /*current_error*/ 1, 695130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_NOT_READY, 696130f4520SKenneth D. Merry /*asc*/ 0x04, 697130f4520SKenneth D. Merry /*ascq*/ 0x02, 698130f4520SKenneth D. Merry SSD_ELEM_NONE); 699130f4520SKenneth D. Merry } 700130f4520SKenneth D. Merry 701130f4520SKenneth D. Merry void 702130f4520SKenneth D. Merry ctl_set_lun_not_ready(struct ctl_scsiio *ctsio) 703130f4520SKenneth D. Merry { 704130f4520SKenneth D. Merry /* "Logical unit not ready, manual intervention required" */ 705130f4520SKenneth D. Merry ctl_set_sense(ctsio, 706130f4520SKenneth D. Merry /*current_error*/ 1, 707130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_NOT_READY, 708130f4520SKenneth D. Merry /*asc*/ 0x04, 709eebb09cfSAlexander Motin /*ascq*/ 0x03, 710130f4520SKenneth D. Merry SSD_ELEM_NONE); 711130f4520SKenneth D. Merry } 712130f4520SKenneth D. Merry 713130f4520SKenneth D. Merry void 714130f4520SKenneth D. Merry ctl_set_illegal_pr_release(struct ctl_scsiio *ctsio) 715130f4520SKenneth D. Merry { 716130f4520SKenneth D. Merry /* "Invalid release of persistent reservation" */ 717130f4520SKenneth D. Merry ctl_set_sense(ctsio, 718130f4520SKenneth D. Merry /*current_error*/ 1, 719130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 720130f4520SKenneth D. Merry /*asc*/ 0x26, 721130f4520SKenneth D. Merry /*ascq*/ 0x04, 722130f4520SKenneth D. Merry SSD_ELEM_NONE); 723130f4520SKenneth D. Merry } 724130f4520SKenneth D. Merry 725130f4520SKenneth D. Merry void 726*7ac58230SAlexander Motin ctl_set_lun_transit(struct ctl_scsiio *ctsio) 727*7ac58230SAlexander Motin { 728*7ac58230SAlexander Motin /* "Logical unit not ready, asymmetric access state transition" */ 729*7ac58230SAlexander Motin ctl_set_sense(ctsio, 730*7ac58230SAlexander Motin /*current_error*/ 1, 731*7ac58230SAlexander Motin /*sense_key*/ SSD_KEY_NOT_READY, 732*7ac58230SAlexander Motin /*asc*/ 0x04, 733*7ac58230SAlexander Motin /*ascq*/ 0x0a, 734*7ac58230SAlexander Motin SSD_ELEM_NONE); 735*7ac58230SAlexander Motin } 736*7ac58230SAlexander Motin 737*7ac58230SAlexander Motin void 738130f4520SKenneth D. Merry ctl_set_lun_standby(struct ctl_scsiio *ctsio) 739130f4520SKenneth D. Merry { 740130f4520SKenneth D. Merry /* "Logical unit not ready, target port in standby state" */ 741130f4520SKenneth D. Merry ctl_set_sense(ctsio, 742130f4520SKenneth D. Merry /*current_error*/ 1, 743130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_NOT_READY, 744130f4520SKenneth D. Merry /*asc*/ 0x04, 745130f4520SKenneth D. Merry /*ascq*/ 0x0b, 746130f4520SKenneth D. Merry SSD_ELEM_NONE); 747130f4520SKenneth D. Merry } 748130f4520SKenneth D. Merry 749130f4520SKenneth D. Merry void 750*7ac58230SAlexander Motin ctl_set_lun_unavail(struct ctl_scsiio *ctsio) 751*7ac58230SAlexander Motin { 752*7ac58230SAlexander Motin /* "Logical unit not ready, target port in unavailable state" */ 753*7ac58230SAlexander Motin ctl_set_sense(ctsio, 754*7ac58230SAlexander Motin /*current_error*/ 1, 755*7ac58230SAlexander Motin /*sense_key*/ SSD_KEY_NOT_READY, 756*7ac58230SAlexander Motin /*asc*/ 0x04, 757*7ac58230SAlexander Motin /*ascq*/ 0x0c, 758*7ac58230SAlexander Motin SSD_ELEM_NONE); 759*7ac58230SAlexander Motin } 760*7ac58230SAlexander Motin 761*7ac58230SAlexander Motin void 762130f4520SKenneth D. Merry ctl_set_medium_format_corrupted(struct ctl_scsiio *ctsio) 763130f4520SKenneth D. Merry { 764130f4520SKenneth D. Merry /* "Medium format corrupted" */ 765130f4520SKenneth D. Merry ctl_set_sense(ctsio, 766130f4520SKenneth D. Merry /*current_error*/ 1, 767130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_MEDIUM_ERROR, 768130f4520SKenneth D. Merry /*asc*/ 0x31, 769130f4520SKenneth D. Merry /*ascq*/ 0x00, 770130f4520SKenneth D. Merry SSD_ELEM_NONE); 771130f4520SKenneth D. Merry } 772130f4520SKenneth D. Merry 773130f4520SKenneth D. Merry void 774130f4520SKenneth D. Merry ctl_set_medium_magazine_inaccessible(struct ctl_scsiio *ctsio) 775130f4520SKenneth D. Merry { 776130f4520SKenneth D. Merry /* "Medium magazine not accessible" */ 777130f4520SKenneth D. Merry ctl_set_sense(ctsio, 778130f4520SKenneth D. Merry /*current_error*/ 1, 779130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_NOT_READY, 780130f4520SKenneth D. Merry /*asc*/ 0x3b, 781130f4520SKenneth D. Merry /*ascq*/ 0x11, 782130f4520SKenneth D. Merry SSD_ELEM_NONE); 783130f4520SKenneth D. Merry } 784130f4520SKenneth D. Merry 785130f4520SKenneth D. Merry void 786130f4520SKenneth D. Merry ctl_set_data_phase_error(struct ctl_scsiio *ctsio) 787130f4520SKenneth D. Merry { 788130f4520SKenneth D. Merry /* "Data phase error" */ 789130f4520SKenneth D. Merry ctl_set_sense(ctsio, 790130f4520SKenneth D. Merry /*current_error*/ 1, 791130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_NOT_READY, 792130f4520SKenneth D. Merry /*asc*/ 0x4b, 793130f4520SKenneth D. Merry /*ascq*/ 0x00, 794130f4520SKenneth D. Merry SSD_ELEM_NONE); 795130f4520SKenneth D. Merry } 796130f4520SKenneth D. Merry 797130f4520SKenneth D. Merry void 798130f4520SKenneth D. Merry ctl_set_reservation_conflict(struct ctl_scsiio *ctsio) 799130f4520SKenneth D. Merry { 800130f4520SKenneth D. Merry struct scsi_sense_data *sense; 801130f4520SKenneth D. Merry 802130f4520SKenneth D. Merry sense = &ctsio->sense_data; 803130f4520SKenneth D. Merry memset(sense, 0, sizeof(*sense)); 804130f4520SKenneth D. Merry ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT; 805130f4520SKenneth D. Merry ctsio->sense_len = 0; 806130f4520SKenneth D. Merry ctsio->io_hdr.status = CTL_SCSI_ERROR; 807130f4520SKenneth D. Merry } 808130f4520SKenneth D. Merry 809130f4520SKenneth D. Merry void 810130f4520SKenneth D. Merry ctl_set_queue_full(struct ctl_scsiio *ctsio) 811130f4520SKenneth D. Merry { 812130f4520SKenneth D. Merry struct scsi_sense_data *sense; 813130f4520SKenneth D. Merry 814130f4520SKenneth D. Merry sense = &ctsio->sense_data; 815130f4520SKenneth D. Merry memset(sense, 0, sizeof(*sense)); 816130f4520SKenneth D. Merry ctsio->scsi_status = SCSI_STATUS_QUEUE_FULL; 817130f4520SKenneth D. Merry ctsio->sense_len = 0; 818130f4520SKenneth D. Merry ctsio->io_hdr.status = CTL_SCSI_ERROR; 819130f4520SKenneth D. Merry } 820130f4520SKenneth D. Merry 821130f4520SKenneth D. Merry void 822130f4520SKenneth D. Merry ctl_set_busy(struct ctl_scsiio *ctsio) 823130f4520SKenneth D. Merry { 824130f4520SKenneth D. Merry struct scsi_sense_data *sense; 825130f4520SKenneth D. Merry 826130f4520SKenneth D. Merry sense = &ctsio->sense_data; 827130f4520SKenneth D. Merry memset(sense, 0, sizeof(*sense)); 828130f4520SKenneth D. Merry ctsio->scsi_status = SCSI_STATUS_BUSY; 829130f4520SKenneth D. Merry ctsio->sense_len = 0; 830130f4520SKenneth D. Merry ctsio->io_hdr.status = CTL_SCSI_ERROR; 831130f4520SKenneth D. Merry } 832130f4520SKenneth D. Merry 833130f4520SKenneth D. Merry void 834b33b96e3SAlexander Motin ctl_set_task_aborted(struct ctl_scsiio *ctsio) 835b33b96e3SAlexander Motin { 836b33b96e3SAlexander Motin struct scsi_sense_data *sense; 837b33b96e3SAlexander Motin 838b33b96e3SAlexander Motin sense = &ctsio->sense_data; 839b33b96e3SAlexander Motin memset(sense, 0, sizeof(*sense)); 840b33b96e3SAlexander Motin ctsio->scsi_status = SCSI_STATUS_TASK_ABORTED; 841b33b96e3SAlexander Motin ctsio->sense_len = 0; 842b33b96e3SAlexander Motin ctsio->io_hdr.status = CTL_CMD_ABORTED; 843b33b96e3SAlexander Motin } 844b33b96e3SAlexander Motin 845b33b96e3SAlexander Motin void 8464fc18ff9SAlexander Motin ctl_set_space_alloc_fail(struct ctl_scsiio *ctsio) 8474fc18ff9SAlexander Motin { 8484fc18ff9SAlexander Motin /* "Space allocation failed write protect" */ 8494fc18ff9SAlexander Motin ctl_set_sense(ctsio, 8504fc18ff9SAlexander Motin /*current_error*/ 1, 8514fc18ff9SAlexander Motin /*sense_key*/ SSD_KEY_DATA_PROTECT, 8524fc18ff9SAlexander Motin /*asc*/ 0x27, 8534fc18ff9SAlexander Motin /*ascq*/ 0x07, 8544fc18ff9SAlexander Motin SSD_ELEM_NONE); 8554fc18ff9SAlexander Motin } 8564fc18ff9SAlexander Motin 8574fc18ff9SAlexander Motin void 858130f4520SKenneth D. Merry ctl_set_success(struct ctl_scsiio *ctsio) 859130f4520SKenneth D. Merry { 860130f4520SKenneth D. Merry struct scsi_sense_data *sense; 861130f4520SKenneth D. Merry 862130f4520SKenneth D. Merry sense = &ctsio->sense_data; 863130f4520SKenneth D. Merry memset(sense, 0, sizeof(*sense)); 864130f4520SKenneth D. Merry ctsio->scsi_status = SCSI_STATUS_OK; 865130f4520SKenneth D. Merry ctsio->sense_len = 0; 866130f4520SKenneth D. Merry ctsio->io_hdr.status = CTL_SUCCESS; 867130f4520SKenneth D. Merry } 868