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_frontend_internal.h> 61130f4520SKenneth D. Merry #include <cam/ctl/ctl_backend.h> 62130f4520SKenneth D. Merry #include <cam/ctl/ctl_ioctl.h> 63130f4520SKenneth D. Merry #include <cam/ctl/ctl_error.h> 64130f4520SKenneth D. Merry #include <cam/ctl/ctl_ha.h> 65130f4520SKenneth D. Merry #include <cam/ctl/ctl_private.h> 66130f4520SKenneth D. Merry 67130f4520SKenneth D. Merry void 68130f4520SKenneth D. Merry ctl_set_sense_data_va(struct scsi_sense_data *sense_data, void *lunptr, 69130f4520SKenneth D. Merry scsi_sense_data_type sense_format, int current_error, 70130f4520SKenneth D. Merry int sense_key, int asc, int ascq, va_list ap) 71130f4520SKenneth D. Merry { 72130f4520SKenneth D. Merry struct ctl_lun *lun; 73130f4520SKenneth D. Merry 74130f4520SKenneth D. Merry lun = (struct ctl_lun *)lunptr; 75130f4520SKenneth D. Merry 76130f4520SKenneth D. Merry /* 77130f4520SKenneth D. Merry * Determine whether to return fixed or descriptor format sense 78130f4520SKenneth D. Merry * data. 79130f4520SKenneth D. Merry */ 80130f4520SKenneth D. Merry if (sense_format == SSD_TYPE_NONE) { 81130f4520SKenneth D. Merry /* 82130f4520SKenneth D. Merry * If the format isn't specified, we only return descriptor 83130f4520SKenneth D. Merry * sense if the LUN exists and descriptor sense is turned 84130f4520SKenneth D. Merry * on for that LUN. 85130f4520SKenneth D. Merry */ 86130f4520SKenneth D. Merry if ((lun != NULL) 87130f4520SKenneth D. Merry && (lun->flags & CTL_LUN_SENSE_DESC)) 88130f4520SKenneth D. Merry sense_format = SSD_TYPE_DESC; 89130f4520SKenneth D. Merry else 90130f4520SKenneth D. Merry sense_format = SSD_TYPE_FIXED; 91130f4520SKenneth D. Merry } 92130f4520SKenneth D. Merry 93130f4520SKenneth D. Merry scsi_set_sense_data_va(sense_data, sense_format, current_error, 94130f4520SKenneth D. Merry sense_key, asc, ascq, ap); 95130f4520SKenneth D. Merry } 96130f4520SKenneth D. Merry 97130f4520SKenneth D. Merry void 98130f4520SKenneth D. Merry ctl_set_sense_data(struct scsi_sense_data *sense_data, void *lunptr, 99130f4520SKenneth D. Merry scsi_sense_data_type sense_format, int current_error, 100130f4520SKenneth D. Merry int sense_key, int asc, int ascq, ...) 101130f4520SKenneth D. Merry { 102130f4520SKenneth D. Merry va_list ap; 103130f4520SKenneth D. Merry 104130f4520SKenneth D. Merry va_start(ap, ascq); 105130f4520SKenneth D. Merry ctl_set_sense_data_va(sense_data, lunptr, sense_format, current_error, 106130f4520SKenneth D. Merry sense_key, asc, ascq, ap); 107130f4520SKenneth D. Merry va_end(ap); 108130f4520SKenneth D. Merry } 109130f4520SKenneth D. Merry 110130f4520SKenneth D. Merry void 111130f4520SKenneth D. Merry ctl_set_sense(struct ctl_scsiio *ctsio, int current_error, int sense_key, 112130f4520SKenneth D. Merry int asc, int ascq, ...) 113130f4520SKenneth D. Merry { 114130f4520SKenneth D. Merry va_list ap; 115130f4520SKenneth D. Merry struct ctl_lun *lun; 116130f4520SKenneth D. Merry 117130f4520SKenneth D. Merry /* 118130f4520SKenneth D. Merry * The LUN can't go away until all of the commands have been 119130f4520SKenneth D. Merry * completed. Therefore we can safely access the LUN structure and 120130f4520SKenneth D. Merry * flags without the lock. 121130f4520SKenneth D. Merry */ 122130f4520SKenneth D. Merry lun = (struct ctl_lun *)ctsio->io_hdr.ctl_private[CTL_PRIV_LUN].ptr; 123130f4520SKenneth D. Merry 124130f4520SKenneth D. Merry va_start(ap, ascq); 125130f4520SKenneth D. Merry ctl_set_sense_data_va(&ctsio->sense_data, 126130f4520SKenneth D. Merry lun, 127130f4520SKenneth D. Merry SSD_TYPE_NONE, 128130f4520SKenneth D. Merry current_error, 129130f4520SKenneth D. Merry sense_key, 130130f4520SKenneth D. Merry asc, 131130f4520SKenneth D. Merry ascq, 132130f4520SKenneth D. Merry ap); 133130f4520SKenneth D. Merry va_end(ap); 134130f4520SKenneth D. Merry 135130f4520SKenneth D. Merry ctsio->scsi_status = SCSI_STATUS_CHECK_COND; 136130f4520SKenneth D. Merry ctsio->sense_len = SSD_FULL_SIZE; 137130f4520SKenneth D. Merry ctsio->io_hdr.status = CTL_SCSI_ERROR | CTL_AUTOSENSE; 138130f4520SKenneth D. Merry } 139130f4520SKenneth D. Merry 140130f4520SKenneth D. Merry /* 141130f4520SKenneth D. Merry * Transform fixed sense data into descriptor sense data. 142130f4520SKenneth D. Merry * 143130f4520SKenneth D. Merry * For simplicity's sake, we assume that both sense structures are 144130f4520SKenneth D. Merry * SSD_FULL_SIZE. Otherwise, the logic gets more complicated. 145130f4520SKenneth D. Merry */ 146130f4520SKenneth D. Merry void 147130f4520SKenneth D. Merry ctl_sense_to_desc(struct scsi_sense_data_fixed *sense_src, 148130f4520SKenneth D. Merry struct scsi_sense_data_desc *sense_dest) 149130f4520SKenneth D. Merry { 150130f4520SKenneth D. Merry struct scsi_sense_stream stream_sense; 151130f4520SKenneth D. Merry int current_error; 152130f4520SKenneth D. Merry uint8_t stream_bits; 153130f4520SKenneth D. Merry 154130f4520SKenneth D. Merry bzero(sense_dest, sizeof(*sense_dest)); 155130f4520SKenneth D. Merry 156130f4520SKenneth D. Merry if ((sense_src->error_code & SSD_ERRCODE) == SSD_DEFERRED_ERROR) 157130f4520SKenneth D. Merry current_error = 0; 158130f4520SKenneth D. Merry else 159130f4520SKenneth D. Merry current_error = 1; 160130f4520SKenneth D. Merry 161130f4520SKenneth D. Merry bzero(&stream_sense, sizeof(stream_sense)); 162130f4520SKenneth D. Merry 163130f4520SKenneth D. Merry /* 164130f4520SKenneth D. Merry * Check to see whether any of the tape-specific bits are set. If 165130f4520SKenneth D. Merry * so, we'll need a stream sense descriptor. 166130f4520SKenneth D. Merry */ 167130f4520SKenneth D. Merry if (sense_src->flags & (SSD_ILI|SSD_EOM|SSD_FILEMARK)) 168130f4520SKenneth D. Merry stream_bits = sense_src->flags & ~SSD_KEY; 169130f4520SKenneth D. Merry else 170130f4520SKenneth D. Merry stream_bits = 0; 171130f4520SKenneth D. Merry 172130f4520SKenneth D. Merry /* 173130f4520SKenneth D. Merry * Utilize our sense setting routine to do the transform. If a 174130f4520SKenneth D. Merry * value is set in the fixed sense data, set it in the descriptor 175130f4520SKenneth D. Merry * data. Otherwise, skip it. 176130f4520SKenneth D. Merry */ 177130f4520SKenneth D. Merry ctl_set_sense_data((struct scsi_sense_data *)sense_dest, 178130f4520SKenneth D. Merry /*lun*/ NULL, 179130f4520SKenneth D. Merry /*sense_format*/ SSD_TYPE_DESC, 180130f4520SKenneth D. Merry current_error, 181130f4520SKenneth D. Merry /*sense_key*/ sense_src->flags & SSD_KEY, 182130f4520SKenneth D. Merry /*asc*/ sense_src->add_sense_code, 183130f4520SKenneth D. Merry /*ascq*/ sense_src->add_sense_code_qual, 184130f4520SKenneth D. Merry 185130f4520SKenneth D. Merry /* Information Bytes */ 186130f4520SKenneth D. Merry (scsi_4btoul(sense_src->info) != 0) ? 187130f4520SKenneth D. Merry SSD_ELEM_INFO : SSD_ELEM_SKIP, 188130f4520SKenneth D. Merry sizeof(sense_src->info), 189130f4520SKenneth D. Merry sense_src->info, 190130f4520SKenneth D. Merry 191130f4520SKenneth D. Merry /* Command specific bytes */ 192130f4520SKenneth D. Merry (scsi_4btoul(sense_src->cmd_spec_info) != 0) ? 193130f4520SKenneth D. Merry SSD_ELEM_COMMAND : SSD_ELEM_SKIP, 194130f4520SKenneth D. Merry sizeof(sense_src->cmd_spec_info), 195130f4520SKenneth D. Merry sense_src->cmd_spec_info, 196130f4520SKenneth D. Merry 197130f4520SKenneth D. Merry /* FRU */ 198130f4520SKenneth D. Merry (sense_src->fru != 0) ? 199130f4520SKenneth D. Merry SSD_ELEM_FRU : SSD_ELEM_SKIP, 200130f4520SKenneth D. Merry sizeof(sense_src->fru), 201130f4520SKenneth D. Merry &sense_src->fru, 202130f4520SKenneth D. Merry 203130f4520SKenneth D. Merry /* Sense Key Specific */ 204130f4520SKenneth D. Merry (sense_src->sense_key_spec[0] & SSD_SCS_VALID) ? 205130f4520SKenneth D. Merry SSD_ELEM_SKS : SSD_ELEM_SKIP, 206130f4520SKenneth D. Merry sizeof(sense_src->sense_key_spec), 207130f4520SKenneth D. Merry sense_src->sense_key_spec, 208130f4520SKenneth D. Merry 209130f4520SKenneth D. Merry /* Tape bits */ 210130f4520SKenneth D. Merry (stream_bits != 0) ? 211130f4520SKenneth D. Merry SSD_ELEM_STREAM : SSD_ELEM_SKIP, 212130f4520SKenneth D. Merry sizeof(stream_bits), 213130f4520SKenneth D. Merry &stream_bits, 214130f4520SKenneth D. Merry 215130f4520SKenneth D. Merry SSD_ELEM_NONE); 216130f4520SKenneth D. Merry } 217130f4520SKenneth D. Merry 218130f4520SKenneth D. Merry /* 219130f4520SKenneth D. Merry * Transform descriptor format sense data into fixed sense data. 220130f4520SKenneth D. Merry * 221130f4520SKenneth D. Merry * Some data may be lost in translation, because there are descriptors 222130f4520SKenneth D. Merry * thant can't be represented as fixed sense data. 223130f4520SKenneth D. Merry * 224130f4520SKenneth D. Merry * For simplicity's sake, we assume that both sense structures are 225130f4520SKenneth D. Merry * SSD_FULL_SIZE. Otherwise, the logic gets more complicated. 226130f4520SKenneth D. Merry */ 227130f4520SKenneth D. Merry void 228130f4520SKenneth D. Merry ctl_sense_to_fixed(struct scsi_sense_data_desc *sense_src, 229130f4520SKenneth D. Merry struct scsi_sense_data_fixed *sense_dest) 230130f4520SKenneth D. Merry { 231130f4520SKenneth D. Merry int current_error; 232130f4520SKenneth D. Merry uint8_t *info_ptr = NULL, *cmd_ptr = NULL, *fru_ptr = NULL; 233130f4520SKenneth D. Merry uint8_t *sks_ptr = NULL, *stream_ptr = NULL; 234130f4520SKenneth D. Merry int info_size = 0, cmd_size = 0, fru_size = 0; 235130f4520SKenneth D. Merry int sks_size = 0, stream_size = 0; 236130f4520SKenneth D. Merry int pos; 237130f4520SKenneth D. Merry 238130f4520SKenneth D. Merry if ((sense_src->error_code & SSD_ERRCODE) == SSD_DESC_CURRENT_ERROR) 239130f4520SKenneth D. Merry current_error = 1; 240130f4520SKenneth D. Merry else 241130f4520SKenneth D. Merry current_error = 0; 242130f4520SKenneth D. Merry 243130f4520SKenneth D. Merry for (pos = 0; pos < (int)(sense_src->extra_len - 1);) { 244130f4520SKenneth D. Merry struct scsi_sense_desc_header *header; 245130f4520SKenneth D. Merry 246130f4520SKenneth D. Merry header = (struct scsi_sense_desc_header *) 247130f4520SKenneth D. Merry &sense_src->sense_desc[pos]; 248130f4520SKenneth D. Merry 249130f4520SKenneth D. Merry /* 250130f4520SKenneth D. Merry * See if this record goes past the end of the sense data. 251130f4520SKenneth D. Merry * It shouldn't, but check just in case. 252130f4520SKenneth D. Merry */ 253130f4520SKenneth D. Merry if ((pos + header->length + sizeof(*header)) > 254130f4520SKenneth D. Merry sense_src->extra_len) 255130f4520SKenneth D. Merry break; 256130f4520SKenneth D. Merry 257130f4520SKenneth D. Merry switch (sense_src->sense_desc[pos]) { 258130f4520SKenneth D. Merry case SSD_DESC_INFO: { 259130f4520SKenneth D. Merry struct scsi_sense_info *info; 260130f4520SKenneth D. Merry 261130f4520SKenneth D. Merry info = (struct scsi_sense_info *)header; 262130f4520SKenneth D. Merry 263130f4520SKenneth D. Merry info_ptr = info->info; 264130f4520SKenneth D. Merry info_size = sizeof(info->info); 265130f4520SKenneth D. Merry 266130f4520SKenneth D. Merry pos += info->length + 267130f4520SKenneth D. Merry sizeof(struct scsi_sense_desc_header); 268130f4520SKenneth D. Merry break; 269130f4520SKenneth D. Merry } 270130f4520SKenneth D. Merry case SSD_DESC_COMMAND: { 271130f4520SKenneth D. Merry struct scsi_sense_command *cmd; 272130f4520SKenneth D. Merry 273130f4520SKenneth D. Merry cmd = (struct scsi_sense_command *)header; 274130f4520SKenneth D. Merry cmd_ptr = cmd->command_info; 275130f4520SKenneth D. Merry cmd_size = sizeof(cmd->command_info); 276130f4520SKenneth D. Merry 277130f4520SKenneth D. Merry pos += cmd->length + 278130f4520SKenneth D. Merry sizeof(struct scsi_sense_desc_header); 279130f4520SKenneth D. Merry break; 280130f4520SKenneth D. Merry } 281130f4520SKenneth D. Merry case SSD_DESC_FRU: { 282130f4520SKenneth D. Merry struct scsi_sense_fru *fru; 283130f4520SKenneth D. Merry 284130f4520SKenneth D. Merry fru = (struct scsi_sense_fru *)header; 285130f4520SKenneth D. Merry fru_ptr = &fru->fru; 286130f4520SKenneth D. Merry fru_size = sizeof(fru->fru); 287130f4520SKenneth D. Merry pos += fru->length + 288130f4520SKenneth D. Merry sizeof(struct scsi_sense_desc_header); 289130f4520SKenneth D. Merry break; 290130f4520SKenneth D. Merry } 291130f4520SKenneth D. Merry case SSD_DESC_SKS: { 292130f4520SKenneth D. Merry struct scsi_sense_sks *sks; 293130f4520SKenneth D. Merry 294130f4520SKenneth D. Merry sks = (struct scsi_sense_sks *)header; 295130f4520SKenneth D. Merry sks_ptr = sks->sense_key_spec; 296130f4520SKenneth D. Merry sks_size = sizeof(sks->sense_key_spec); 297130f4520SKenneth D. Merry 298130f4520SKenneth D. Merry pos = sks->length + 299130f4520SKenneth D. Merry sizeof(struct scsi_sense_desc_header); 300130f4520SKenneth D. Merry break; 301130f4520SKenneth D. Merry } 302130f4520SKenneth D. Merry case SSD_DESC_STREAM: { 303130f4520SKenneth D. Merry struct scsi_sense_stream *stream_sense; 304130f4520SKenneth D. Merry 305130f4520SKenneth D. Merry stream_sense = (struct scsi_sense_stream *)header; 306130f4520SKenneth D. Merry stream_ptr = &stream_sense->byte3; 307130f4520SKenneth D. Merry stream_size = sizeof(stream_sense->byte3); 308130f4520SKenneth D. Merry pos = stream_sense->length + 309130f4520SKenneth D. Merry sizeof(struct scsi_sense_desc_header); 310130f4520SKenneth D. Merry break; 311130f4520SKenneth D. Merry } 312130f4520SKenneth D. Merry default: 313130f4520SKenneth D. Merry /* 314130f4520SKenneth D. Merry * We don't recognize this particular sense 315130f4520SKenneth D. Merry * descriptor type, so just skip it. 316130f4520SKenneth D. Merry */ 317130f4520SKenneth D. Merry pos += sizeof(*header) + header->length; 318130f4520SKenneth D. Merry break; 319130f4520SKenneth D. Merry } 320130f4520SKenneth D. Merry } 321130f4520SKenneth D. Merry 322130f4520SKenneth D. Merry ctl_set_sense_data((struct scsi_sense_data *)sense_dest, 323130f4520SKenneth D. Merry /*lun*/ NULL, 324130f4520SKenneth D. Merry /*sense_format*/ SSD_TYPE_FIXED, 325130f4520SKenneth D. Merry current_error, 326130f4520SKenneth D. Merry /*sense_key*/ sense_src->sense_key & SSD_KEY, 327130f4520SKenneth D. Merry /*asc*/ sense_src->add_sense_code, 328130f4520SKenneth D. Merry /*ascq*/ sense_src->add_sense_code_qual, 329130f4520SKenneth D. Merry 330130f4520SKenneth D. Merry /* Information Bytes */ 331130f4520SKenneth D. Merry (info_ptr != NULL) ? SSD_ELEM_INFO : SSD_ELEM_SKIP, 332130f4520SKenneth D. Merry info_size, 333130f4520SKenneth D. Merry info_ptr, 334130f4520SKenneth D. Merry 335130f4520SKenneth D. Merry /* Command specific bytes */ 336130f4520SKenneth D. Merry (cmd_ptr != NULL) ? SSD_ELEM_COMMAND : SSD_ELEM_SKIP, 337130f4520SKenneth D. Merry cmd_size, 338130f4520SKenneth D. Merry cmd_ptr, 339130f4520SKenneth D. Merry 340130f4520SKenneth D. Merry /* FRU */ 341130f4520SKenneth D. Merry (fru_ptr != NULL) ? SSD_ELEM_FRU : SSD_ELEM_SKIP, 342130f4520SKenneth D. Merry fru_size, 343130f4520SKenneth D. Merry fru_ptr, 344130f4520SKenneth D. Merry 345130f4520SKenneth D. Merry /* Sense Key Specific */ 346130f4520SKenneth D. Merry (sks_ptr != NULL) ? SSD_ELEM_SKS : SSD_ELEM_SKIP, 347130f4520SKenneth D. Merry sks_size, 348130f4520SKenneth D. Merry sks_ptr, 349130f4520SKenneth D. Merry 350130f4520SKenneth D. Merry /* Tape bits */ 351130f4520SKenneth D. Merry (stream_ptr != NULL) ? SSD_ELEM_STREAM : SSD_ELEM_SKIP, 352130f4520SKenneth D. Merry stream_size, 353130f4520SKenneth D. Merry stream_ptr, 354130f4520SKenneth D. Merry 355130f4520SKenneth D. Merry SSD_ELEM_NONE); 356130f4520SKenneth D. Merry } 357130f4520SKenneth D. Merry 358130f4520SKenneth D. Merry void 359130f4520SKenneth D. Merry ctl_set_ua(struct ctl_scsiio *ctsio, int asc, int ascq) 360130f4520SKenneth D. Merry { 361130f4520SKenneth D. Merry ctl_set_sense(ctsio, 362130f4520SKenneth D. Merry /*current_error*/ 1, 363130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_UNIT_ATTENTION, 364130f4520SKenneth D. Merry asc, 365130f4520SKenneth D. Merry ascq, 366130f4520SKenneth D. Merry SSD_ELEM_NONE); 367130f4520SKenneth D. Merry } 368130f4520SKenneth D. Merry 369130f4520SKenneth D. Merry ctl_ua_type 370130f4520SKenneth D. Merry ctl_build_ua(ctl_ua_type ua_type, struct scsi_sense_data *sense, 3712a2443d8SKenneth D. Merry scsi_sense_data_type sense_format) 372130f4520SKenneth D. Merry { 373130f4520SKenneth D. Merry ctl_ua_type ua_to_build; 374130f4520SKenneth D. Merry int i, asc, ascq; 375130f4520SKenneth D. Merry 376130f4520SKenneth D. Merry if (ua_type == CTL_UA_NONE) 377130f4520SKenneth D. Merry return (ua_type); 378130f4520SKenneth D. Merry 379130f4520SKenneth D. Merry ua_to_build = CTL_UA_NONE; 380130f4520SKenneth D. Merry 381130f4520SKenneth D. Merry for (i = 0; i < (sizeof(ua_type) * 8); i++) { 382130f4520SKenneth D. Merry if (ua_type & (1 << i)) { 383130f4520SKenneth D. Merry ua_to_build = 1 << i; 384130f4520SKenneth D. Merry break; 385130f4520SKenneth D. Merry } 386130f4520SKenneth D. Merry } 387130f4520SKenneth D. Merry 388130f4520SKenneth D. Merry switch (ua_to_build) { 389130f4520SKenneth D. Merry case CTL_UA_POWERON: 390130f4520SKenneth D. Merry /* 29h/01h POWER ON OCCURRED */ 391130f4520SKenneth D. Merry asc = 0x29; 392130f4520SKenneth D. Merry ascq = 0x01; 393130f4520SKenneth D. Merry break; 394130f4520SKenneth D. Merry case CTL_UA_BUS_RESET: 395130f4520SKenneth D. Merry /* 29h/02h SCSI BUS RESET OCCURRED */ 396130f4520SKenneth D. Merry asc = 0x29; 397130f4520SKenneth D. Merry ascq = 0x02; 398130f4520SKenneth D. Merry break; 399130f4520SKenneth D. Merry case CTL_UA_TARG_RESET: 400130f4520SKenneth D. Merry /* 29h/03h BUS DEVICE RESET FUNCTION OCCURRED*/ 401130f4520SKenneth D. Merry asc = 0x29; 402130f4520SKenneth D. Merry ascq = 0x03; 403130f4520SKenneth D. Merry break; 4040020682bSAlexander Motin case CTL_UA_I_T_NEXUS_LOSS: 4050020682bSAlexander Motin /* 29h/07h I_T NEXUS LOSS OCCURRED */ 4060020682bSAlexander Motin asc = 0x29; 4070020682bSAlexander Motin ascq = 0x07; 4080020682bSAlexander Motin break; 409130f4520SKenneth D. Merry case CTL_UA_LUN_RESET: 410130f4520SKenneth D. Merry /* 29h/00h POWER ON, RESET, OR BUS DEVICE RESET OCCURRED */ 411130f4520SKenneth D. Merry /* 412130f4520SKenneth D. Merry * Since we don't have a specific ASC/ASCQ pair for a LUN 413130f4520SKenneth D. Merry * reset, just return the generic reset code. 414130f4520SKenneth D. Merry */ 415130f4520SKenneth D. Merry asc = 0x29; 416130f4520SKenneth D. Merry ascq = 0x00; 417130f4520SKenneth D. Merry break; 418130f4520SKenneth D. Merry case CTL_UA_LUN_CHANGE: 419130f4520SKenneth D. Merry /* 3Fh/0Eh REPORTED LUNS DATA HAS CHANGED */ 420130f4520SKenneth D. Merry asc = 0x3F; 421130f4520SKenneth D. Merry ascq = 0x0E; 422130f4520SKenneth D. Merry break; 423130f4520SKenneth D. Merry case CTL_UA_MODE_CHANGE: 424130f4520SKenneth D. Merry /* 2Ah/01h MODE PARAMETERS CHANGED */ 425130f4520SKenneth D. Merry asc = 0x2A; 426130f4520SKenneth D. Merry ascq = 0x01; 427130f4520SKenneth D. Merry break; 428130f4520SKenneth D. Merry case CTL_UA_LOG_CHANGE: 429130f4520SKenneth D. Merry /* 2Ah/02h LOG PARAMETERS CHANGED */ 430130f4520SKenneth D. Merry asc = 0x2A; 431130f4520SKenneth D. Merry ascq = 0x02; 432130f4520SKenneth D. Merry break; 433130f4520SKenneth D. Merry case CTL_UA_LVD: 434130f4520SKenneth D. Merry /* 29h/06h TRANSCEIVER MODE CHANGED TO LVD */ 435130f4520SKenneth D. Merry asc = 0x29; 436130f4520SKenneth D. Merry ascq = 0x06; 437130f4520SKenneth D. Merry break; 438130f4520SKenneth D. Merry case CTL_UA_SE: 439130f4520SKenneth D. Merry /* 29h/05h TRANSCEIVER MODE CHANGED TO SINGLE-ENDED */ 440130f4520SKenneth D. Merry asc = 0x29; 441130f4520SKenneth D. Merry ascq = 0x05; 442130f4520SKenneth D. Merry break; 443130f4520SKenneth D. Merry case CTL_UA_RES_PREEMPT: 444130f4520SKenneth D. Merry /* 2Ah/03h RESERVATIONS PREEMPTED */ 445130f4520SKenneth D. Merry asc = 0x2A; 446130f4520SKenneth D. Merry ascq = 0x03; 447130f4520SKenneth D. Merry break; 448130f4520SKenneth D. Merry case CTL_UA_RES_RELEASE: 449130f4520SKenneth D. Merry /* 2Ah/04h RESERVATIONS RELEASED */ 450130f4520SKenneth D. Merry asc = 0x2A; 451130f4520SKenneth D. Merry ascq = 0x04; 452130f4520SKenneth D. Merry break; 453130f4520SKenneth D. Merry case CTL_UA_REG_PREEMPT: 454130f4520SKenneth D. Merry /* 2Ah/05h REGISTRATIONS PREEMPTED */ 455130f4520SKenneth D. Merry asc = 0x2A; 456130f4520SKenneth D. Merry ascq = 0x05; 457130f4520SKenneth D. Merry break; 458130f4520SKenneth D. Merry case CTL_UA_ASYM_ACC_CHANGE: 459130f4520SKenneth D. Merry /* 2Ah/06n ASYMMETRIC ACCESS STATE CHANGED */ 460130f4520SKenneth D. Merry asc = 0x2A; 461130f4520SKenneth D. Merry ascq = 0x06; 462130f4520SKenneth D. Merry break; 46381177295SEdward Tomasz Napierala case CTL_UA_CAPACITY_CHANGED: 46481177295SEdward Tomasz Napierala /* 2Ah/09n CAPACITY DATA HAS CHANGED */ 46581177295SEdward Tomasz Napierala asc = 0x2A; 46681177295SEdward Tomasz Napierala ascq = 0x09; 46781177295SEdward Tomasz Napierala break; 468130f4520SKenneth D. Merry default: 469130f4520SKenneth D. Merry ua_to_build = CTL_UA_NONE; 470130f4520SKenneth D. Merry return (ua_to_build); 471130f4520SKenneth D. Merry break; /* NOTREACHED */ 472130f4520SKenneth D. Merry } 473130f4520SKenneth D. Merry 474130f4520SKenneth D. Merry ctl_set_sense_data(sense, 475130f4520SKenneth D. Merry /*lun*/ NULL, 476130f4520SKenneth D. Merry sense_format, 477130f4520SKenneth D. Merry /*current_error*/ 1, 478130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_UNIT_ATTENTION, 479130f4520SKenneth D. Merry asc, 480130f4520SKenneth D. Merry ascq, 481130f4520SKenneth D. Merry SSD_ELEM_NONE); 482130f4520SKenneth D. Merry 483130f4520SKenneth D. Merry return (ua_to_build); 484130f4520SKenneth D. Merry } 485130f4520SKenneth D. Merry 486130f4520SKenneth D. Merry void 487130f4520SKenneth D. Merry ctl_set_overlapped_cmd(struct ctl_scsiio *ctsio) 488130f4520SKenneth D. Merry { 489130f4520SKenneth D. Merry /* OVERLAPPED COMMANDS ATTEMPTED */ 490130f4520SKenneth D. Merry ctl_set_sense(ctsio, 491130f4520SKenneth D. Merry /*current_error*/ 1, 492130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 493130f4520SKenneth D. Merry /*asc*/ 0x4E, 494130f4520SKenneth D. Merry /*ascq*/ 0x00, 495130f4520SKenneth D. Merry SSD_ELEM_NONE); 496130f4520SKenneth D. Merry } 497130f4520SKenneth D. Merry 498130f4520SKenneth D. Merry void 499130f4520SKenneth D. Merry ctl_set_overlapped_tag(struct ctl_scsiio *ctsio, uint8_t tag) 500130f4520SKenneth D. Merry { 501130f4520SKenneth D. Merry /* TAGGED OVERLAPPED COMMANDS (NN = QUEUE TAG) */ 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*/ 0x4D, 506130f4520SKenneth D. Merry /*ascq*/ tag, 507130f4520SKenneth D. Merry SSD_ELEM_NONE); 508130f4520SKenneth D. Merry } 509130f4520SKenneth D. Merry 510130f4520SKenneth D. Merry /* 511130f4520SKenneth D. Merry * Tell the user that there was a problem with the command or data he sent. 512130f4520SKenneth D. Merry */ 513130f4520SKenneth D. Merry void 514130f4520SKenneth D. Merry ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command, 515130f4520SKenneth D. Merry int field, int bit_valid, int bit) 516130f4520SKenneth D. Merry { 517130f4520SKenneth D. Merry uint8_t sks[3]; 518130f4520SKenneth D. Merry int asc; 519130f4520SKenneth D. Merry 520130f4520SKenneth D. Merry if (command != 0) { 521130f4520SKenneth D. Merry /* "Invalid field in CDB" */ 522130f4520SKenneth D. Merry asc = 0x24; 523130f4520SKenneth D. Merry } else { 524130f4520SKenneth D. Merry /* "Invalid field in parameter list" */ 525130f4520SKenneth D. Merry asc = 0x26; 526130f4520SKenneth D. Merry } 527130f4520SKenneth D. Merry 528130f4520SKenneth D. Merry if (sks_valid) { 529130f4520SKenneth D. Merry sks[0] = SSD_SCS_VALID; 530130f4520SKenneth D. Merry if (command) 531130f4520SKenneth D. Merry sks[0] |= SSD_FIELDPTR_CMD; 532130f4520SKenneth D. Merry scsi_ulto2b(field, &sks[1]); 533130f4520SKenneth D. Merry 534130f4520SKenneth D. Merry if (bit_valid) 535130f4520SKenneth D. Merry sks[0] |= SSD_BITPTR_VALID | bit; 536130f4520SKenneth D. Merry } 537130f4520SKenneth D. Merry 538130f4520SKenneth D. Merry ctl_set_sense(ctsio, 539130f4520SKenneth D. Merry /*current_error*/ 1, 540130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 541130f4520SKenneth D. Merry asc, 542130f4520SKenneth D. Merry /*ascq*/ 0x00, 543130f4520SKenneth D. Merry /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP, 544130f4520SKenneth D. Merry /*size*/ sizeof(sks), 545130f4520SKenneth D. Merry /*data*/ sks, 546130f4520SKenneth D. Merry SSD_ELEM_NONE); 547130f4520SKenneth D. Merry } 548130f4520SKenneth D. Merry 549130f4520SKenneth D. Merry void 550130f4520SKenneth D. Merry ctl_set_invalid_opcode(struct ctl_scsiio *ctsio) 551130f4520SKenneth D. Merry { 552130f4520SKenneth D. Merry struct scsi_sense_data *sense; 553130f4520SKenneth D. Merry uint8_t sks[3]; 554130f4520SKenneth D. Merry 555130f4520SKenneth D. Merry sense = &ctsio->sense_data; 556130f4520SKenneth D. Merry 557130f4520SKenneth D. Merry sks[0] = SSD_SCS_VALID | SSD_FIELDPTR_CMD; 558130f4520SKenneth D. Merry scsi_ulto2b(0, &sks[1]); 559130f4520SKenneth D. Merry 560130f4520SKenneth D. Merry /* "Invalid command operation code" */ 561130f4520SKenneth D. Merry ctl_set_sense(ctsio, 562130f4520SKenneth D. Merry /*current_error*/ 1, 563130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 564130f4520SKenneth D. Merry /*asc*/ 0x20, 565130f4520SKenneth D. Merry /*ascq*/ 0x00, 566130f4520SKenneth D. Merry /*type*/ SSD_ELEM_SKS, 567130f4520SKenneth D. Merry /*size*/ sizeof(sks), 568130f4520SKenneth D. Merry /*data*/ sks, 569130f4520SKenneth D. Merry SSD_ELEM_NONE); 570130f4520SKenneth D. Merry } 571130f4520SKenneth D. Merry 572130f4520SKenneth D. Merry void 573130f4520SKenneth D. Merry ctl_set_param_len_error(struct ctl_scsiio *ctsio) 574130f4520SKenneth D. Merry { 575130f4520SKenneth D. Merry /* "Parameter list length error" */ 576130f4520SKenneth D. Merry ctl_set_sense(ctsio, 577130f4520SKenneth D. Merry /*current_error*/ 1, 578130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 579130f4520SKenneth D. Merry /*asc*/ 0x1a, 580130f4520SKenneth D. Merry /*ascq*/ 0x00, 581130f4520SKenneth D. Merry SSD_ELEM_NONE); 582130f4520SKenneth D. Merry } 583130f4520SKenneth D. Merry 584130f4520SKenneth D. Merry void 585130f4520SKenneth D. Merry ctl_set_already_locked(struct ctl_scsiio *ctsio) 586130f4520SKenneth D. Merry { 587130f4520SKenneth D. Merry /* Vendor unique "Somebody already is locked" */ 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*/ 0x81, 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_unsupported_lun(struct ctl_scsiio *ctsio) 598130f4520SKenneth D. Merry { 599130f4520SKenneth D. Merry /* "Logical unit not supported" */ 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*/ 0x25, 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_internal_failure(struct ctl_scsiio *ctsio, int sks_valid, 610130f4520SKenneth D. Merry uint16_t retry_count) 611130f4520SKenneth D. Merry { 612130f4520SKenneth D. Merry uint8_t sks[3]; 613130f4520SKenneth D. Merry 614130f4520SKenneth D. Merry if (sks_valid) { 615130f4520SKenneth D. Merry sks[0] = SSD_SCS_VALID; 616130f4520SKenneth D. Merry sks[1] = (retry_count >> 8) & 0xff; 617130f4520SKenneth D. Merry sks[2] = retry_count & 0xff; 618130f4520SKenneth D. Merry } 619130f4520SKenneth D. Merry 620130f4520SKenneth D. Merry /* "Internal target failure" */ 621130f4520SKenneth D. Merry ctl_set_sense(ctsio, 622130f4520SKenneth D. Merry /*current_error*/ 1, 623130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_HARDWARE_ERROR, 624130f4520SKenneth D. Merry /*asc*/ 0x44, 625130f4520SKenneth D. Merry /*ascq*/ 0x00, 626130f4520SKenneth D. Merry /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP, 627130f4520SKenneth D. Merry /*size*/ sizeof(sks), 628130f4520SKenneth D. Merry /*data*/ sks, 629130f4520SKenneth D. Merry SSD_ELEM_NONE); 630130f4520SKenneth D. Merry } 631130f4520SKenneth D. Merry 632130f4520SKenneth D. Merry void 633130f4520SKenneth D. Merry ctl_set_medium_error(struct ctl_scsiio *ctsio) 634130f4520SKenneth D. Merry { 635130f4520SKenneth D. Merry if ((ctsio->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) { 636130f4520SKenneth D. Merry /* "Unrecovered read error" */ 637130f4520SKenneth D. Merry ctl_set_sense(ctsio, 638130f4520SKenneth D. Merry /*current_error*/ 1, 639130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_MEDIUM_ERROR, 640130f4520SKenneth D. Merry /*asc*/ 0x11, 641130f4520SKenneth D. Merry /*ascq*/ 0x00, 642130f4520SKenneth D. Merry SSD_ELEM_NONE); 643130f4520SKenneth D. Merry } else { 644130f4520SKenneth D. Merry /* "Write error - auto reallocation failed" */ 645130f4520SKenneth D. Merry ctl_set_sense(ctsio, 646130f4520SKenneth D. Merry /*current_error*/ 1, 647130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_MEDIUM_ERROR, 648130f4520SKenneth D. Merry /*asc*/ 0x0C, 649130f4520SKenneth D. Merry /*ascq*/ 0x02, 650130f4520SKenneth D. Merry SSD_ELEM_NONE); 651130f4520SKenneth D. Merry } 652130f4520SKenneth D. Merry } 653130f4520SKenneth D. Merry 654130f4520SKenneth D. Merry void 655130f4520SKenneth D. Merry ctl_set_aborted(struct ctl_scsiio *ctsio) 656130f4520SKenneth D. Merry { 657130f4520SKenneth D. Merry ctl_set_sense(ctsio, 658130f4520SKenneth D. Merry /*current_error*/ 1, 659130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ABORTED_COMMAND, 660130f4520SKenneth D. Merry /*asc*/ 0x45, 661130f4520SKenneth D. Merry /*ascq*/ 0x00, 662130f4520SKenneth D. Merry SSD_ELEM_NONE); 663130f4520SKenneth D. Merry } 664130f4520SKenneth D. Merry 665130f4520SKenneth D. Merry void 666130f4520SKenneth D. Merry ctl_set_lba_out_of_range(struct ctl_scsiio *ctsio) 667130f4520SKenneth D. Merry { 668130f4520SKenneth D. Merry /* "Logical block address out of range" */ 669130f4520SKenneth D. Merry ctl_set_sense(ctsio, 670130f4520SKenneth D. Merry /*current_error*/ 1, 671130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 672130f4520SKenneth D. Merry /*asc*/ 0x21, 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_lun_stopped(struct ctl_scsiio *ctsio) 679130f4520SKenneth D. Merry { 680130f4520SKenneth D. Merry /* "Logical unit not ready, initializing cmd. required" */ 681130f4520SKenneth D. Merry ctl_set_sense(ctsio, 682130f4520SKenneth D. Merry /*current_error*/ 1, 683130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_NOT_READY, 684130f4520SKenneth D. Merry /*asc*/ 0x04, 685130f4520SKenneth D. Merry /*ascq*/ 0x02, 686130f4520SKenneth D. Merry SSD_ELEM_NONE); 687130f4520SKenneth D. Merry } 688130f4520SKenneth D. Merry 689130f4520SKenneth D. Merry void 690130f4520SKenneth D. Merry ctl_set_lun_not_ready(struct ctl_scsiio *ctsio) 691130f4520SKenneth D. Merry { 692130f4520SKenneth D. Merry /* "Logical unit not ready, manual intervention 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*/ 0x05, 698130f4520SKenneth D. Merry SSD_ELEM_NONE); 699130f4520SKenneth D. Merry } 700130f4520SKenneth D. Merry 701130f4520SKenneth D. Merry void 702130f4520SKenneth D. Merry ctl_set_illegal_pr_release(struct ctl_scsiio *ctsio) 703130f4520SKenneth D. Merry { 704130f4520SKenneth D. Merry /* "Invalid release of persistent reservation" */ 705130f4520SKenneth D. Merry ctl_set_sense(ctsio, 706130f4520SKenneth D. Merry /*current_error*/ 1, 707130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 708130f4520SKenneth D. Merry /*asc*/ 0x26, 709130f4520SKenneth D. Merry /*ascq*/ 0x04, 710130f4520SKenneth D. Merry SSD_ELEM_NONE); 711130f4520SKenneth D. Merry } 712130f4520SKenneth D. Merry 713130f4520SKenneth D. Merry void 714130f4520SKenneth D. Merry ctl_set_lun_standby(struct ctl_scsiio *ctsio) 715130f4520SKenneth D. Merry { 716130f4520SKenneth D. Merry /* "Logical unit not ready, target port in standby state" */ 717130f4520SKenneth D. Merry ctl_set_sense(ctsio, 718130f4520SKenneth D. Merry /*current_error*/ 1, 719130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_NOT_READY, 720130f4520SKenneth D. Merry /*asc*/ 0x04, 721130f4520SKenneth D. Merry /*ascq*/ 0x0b, 722130f4520SKenneth D. Merry SSD_ELEM_NONE); 723130f4520SKenneth D. Merry } 724130f4520SKenneth D. Merry 725130f4520SKenneth D. Merry void 726130f4520SKenneth D. Merry ctl_set_medium_format_corrupted(struct ctl_scsiio *ctsio) 727130f4520SKenneth D. Merry { 728130f4520SKenneth D. Merry /* "Medium format corrupted" */ 729130f4520SKenneth D. Merry ctl_set_sense(ctsio, 730130f4520SKenneth D. Merry /*current_error*/ 1, 731130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_MEDIUM_ERROR, 732130f4520SKenneth D. Merry /*asc*/ 0x31, 733130f4520SKenneth D. Merry /*ascq*/ 0x00, 734130f4520SKenneth D. Merry SSD_ELEM_NONE); 735130f4520SKenneth D. Merry } 736130f4520SKenneth D. Merry 737130f4520SKenneth D. Merry void 738130f4520SKenneth D. Merry ctl_set_medium_magazine_inaccessible(struct ctl_scsiio *ctsio) 739130f4520SKenneth D. Merry { 740130f4520SKenneth D. Merry /* "Medium magazine not accessible" */ 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*/ 0x3b, 745130f4520SKenneth D. Merry /*ascq*/ 0x11, 746130f4520SKenneth D. Merry SSD_ELEM_NONE); 747130f4520SKenneth D. Merry } 748130f4520SKenneth D. Merry 749130f4520SKenneth D. Merry void 750130f4520SKenneth D. Merry ctl_set_data_phase_error(struct ctl_scsiio *ctsio) 751130f4520SKenneth D. Merry { 752130f4520SKenneth D. Merry /* "Data phase error" */ 753130f4520SKenneth D. Merry ctl_set_sense(ctsio, 754130f4520SKenneth D. Merry /*current_error*/ 1, 755130f4520SKenneth D. Merry /*sense_key*/ SSD_KEY_NOT_READY, 756130f4520SKenneth D. Merry /*asc*/ 0x4b, 757130f4520SKenneth D. Merry /*ascq*/ 0x00, 758130f4520SKenneth D. Merry SSD_ELEM_NONE); 759130f4520SKenneth D. Merry } 760130f4520SKenneth D. Merry 761130f4520SKenneth D. Merry void 762130f4520SKenneth D. Merry ctl_set_reservation_conflict(struct ctl_scsiio *ctsio) 763130f4520SKenneth D. Merry { 764130f4520SKenneth D. Merry struct scsi_sense_data *sense; 765130f4520SKenneth D. Merry 766130f4520SKenneth D. Merry sense = &ctsio->sense_data; 767130f4520SKenneth D. Merry memset(sense, 0, sizeof(*sense)); 768130f4520SKenneth D. Merry ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT; 769130f4520SKenneth D. Merry ctsio->sense_len = 0; 770130f4520SKenneth D. Merry ctsio->io_hdr.status = CTL_SCSI_ERROR; 771130f4520SKenneth D. Merry } 772130f4520SKenneth D. Merry 773130f4520SKenneth D. Merry void 774130f4520SKenneth D. Merry ctl_set_queue_full(struct ctl_scsiio *ctsio) 775130f4520SKenneth D. Merry { 776130f4520SKenneth D. Merry struct scsi_sense_data *sense; 777130f4520SKenneth D. Merry 778130f4520SKenneth D. Merry sense = &ctsio->sense_data; 779130f4520SKenneth D. Merry memset(sense, 0, sizeof(*sense)); 780130f4520SKenneth D. Merry ctsio->scsi_status = SCSI_STATUS_QUEUE_FULL; 781130f4520SKenneth D. Merry ctsio->sense_len = 0; 782130f4520SKenneth D. Merry ctsio->io_hdr.status = CTL_SCSI_ERROR; 783130f4520SKenneth D. Merry } 784130f4520SKenneth D. Merry 785130f4520SKenneth D. Merry void 786130f4520SKenneth D. Merry ctl_set_busy(struct ctl_scsiio *ctsio) 787130f4520SKenneth D. Merry { 788130f4520SKenneth D. Merry struct scsi_sense_data *sense; 789130f4520SKenneth D. Merry 790130f4520SKenneth D. Merry sense = &ctsio->sense_data; 791130f4520SKenneth D. Merry memset(sense, 0, sizeof(*sense)); 792130f4520SKenneth D. Merry ctsio->scsi_status = SCSI_STATUS_BUSY; 793130f4520SKenneth D. Merry ctsio->sense_len = 0; 794130f4520SKenneth D. Merry ctsio->io_hdr.status = CTL_SCSI_ERROR; 795130f4520SKenneth D. Merry } 796130f4520SKenneth D. Merry 797130f4520SKenneth D. Merry void 798*b33b96e3SAlexander Motin ctl_set_task_aborted(struct ctl_scsiio *ctsio) 799*b33b96e3SAlexander Motin { 800*b33b96e3SAlexander Motin struct scsi_sense_data *sense; 801*b33b96e3SAlexander Motin 802*b33b96e3SAlexander Motin sense = &ctsio->sense_data; 803*b33b96e3SAlexander Motin memset(sense, 0, sizeof(*sense)); 804*b33b96e3SAlexander Motin ctsio->scsi_status = SCSI_STATUS_TASK_ABORTED; 805*b33b96e3SAlexander Motin ctsio->sense_len = 0; 806*b33b96e3SAlexander Motin ctsio->io_hdr.status = CTL_CMD_ABORTED; 807*b33b96e3SAlexander Motin } 808*b33b96e3SAlexander Motin 809*b33b96e3SAlexander Motin void 810130f4520SKenneth D. Merry ctl_set_success(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_OK; 817130f4520SKenneth D. Merry ctsio->sense_len = 0; 818130f4520SKenneth D. Merry ctsio->io_hdr.status = CTL_SUCCESS; 819130f4520SKenneth D. Merry } 820