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