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