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