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