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