ctl_error.c revision 311407
1/*- 2 * Copyright (c) 2003-2009 Silicon Graphics International Corp. 3 * Copyright (c) 2011 Spectra Logic Corporation 4 * Copyright (c) 2014-2015 Alexander Motin <mav@FreeBSD.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification. 13 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 14 * substantially similar to the "NO WARRANTY" disclaimer below 15 * ("Disclaimer") and any redistribution must be conditioned upon 16 * including a substantially similar Disclaimer requirement for further 17 * binary redistribution. 18 * 19 * NO WARRANTY 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 29 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGES. 31 * 32 * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_error.c#2 $ 33 */ 34/* 35 * CAM Target Layer error reporting routines. 36 * 37 * Author: Ken Merry <ken@FreeBSD.org> 38 */ 39 40#include <sys/cdefs.h> 41__FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl_error.c 311407 2017-01-05 11:28:47Z mav $"); 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/kernel.h> 46#include <sys/types.h> 47#include <sys/malloc.h> 48#include <sys/lock.h> 49#include <sys/mutex.h> 50#include <sys/condvar.h> 51#include <sys/stddef.h> 52#include <sys/ctype.h> 53#include <sys/sysctl.h> 54#include <machine/stdarg.h> 55 56#include <cam/scsi/scsi_all.h> 57#include <cam/scsi/scsi_da.h> 58#include <cam/ctl/ctl_io.h> 59#include <cam/ctl/ctl.h> 60#include <cam/ctl/ctl_frontend.h> 61#include <cam/ctl/ctl_backend.h> 62#include <cam/ctl/ctl_ioctl.h> 63#include <cam/ctl/ctl_error.h> 64#include <cam/ctl/ctl_ha.h> 65#include <cam/ctl/ctl_private.h> 66 67void 68ctl_set_sense_data_va(struct scsi_sense_data *sense_data, void *lunptr, 69 scsi_sense_data_type sense_format, int current_error, 70 int sense_key, int asc, int ascq, va_list ap) 71{ 72 struct ctl_lun *lun; 73 74 lun = (struct ctl_lun *)lunptr; 75 76 /* 77 * Determine whether to return fixed or descriptor format sense 78 * data. 79 */ 80 if (sense_format == SSD_TYPE_NONE) { 81 /* 82 * If the format isn't specified, we only return descriptor 83 * sense if the LUN exists and descriptor sense is turned 84 * on for that LUN. 85 */ 86 if ((lun != NULL) && (lun->MODE_CTRL.rlec & SCP_DSENSE)) 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 96void 97ctl_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 109void 110ctl_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 */ 145void 146ctl_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 */ 226void 227ctl_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 357void 358ctl_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 368static void 369ctl_ua_to_acsq(struct ctl_lun *lun, ctl_ua_type ua_to_build, int *asc, 370 int *ascq, ctl_ua_type *ua_to_clear, uint8_t **info) 371{ 372 373 switch (ua_to_build) { 374 case CTL_UA_POWERON: 375 /* 29h/01h POWER ON OCCURRED */ 376 *asc = 0x29; 377 *ascq = 0x01; 378 *ua_to_clear = ~0; 379 break; 380 case CTL_UA_BUS_RESET: 381 /* 29h/02h SCSI BUS RESET OCCURRED */ 382 *asc = 0x29; 383 *ascq = 0x02; 384 *ua_to_clear = ~0; 385 break; 386 case CTL_UA_TARG_RESET: 387 /* 29h/03h BUS DEVICE RESET FUNCTION OCCURRED*/ 388 *asc = 0x29; 389 *ascq = 0x03; 390 *ua_to_clear = ~0; 391 break; 392 case CTL_UA_I_T_NEXUS_LOSS: 393 /* 29h/07h I_T NEXUS LOSS OCCURRED */ 394 *asc = 0x29; 395 *ascq = 0x07; 396 *ua_to_clear = ~0; 397 break; 398 case CTL_UA_LUN_RESET: 399 /* 29h/00h POWER ON, RESET, OR BUS DEVICE RESET OCCURRED */ 400 /* 401 * Since we don't have a specific ASC/ASCQ pair for a LUN 402 * reset, just return the generic reset code. 403 */ 404 *asc = 0x29; 405 *ascq = 0x00; 406 break; 407 case CTL_UA_LUN_CHANGE: 408 /* 3Fh/0Eh REPORTED LUNS DATA HAS CHANGED */ 409 *asc = 0x3F; 410 *ascq = 0x0E; 411 break; 412 case CTL_UA_MODE_CHANGE: 413 /* 2Ah/01h MODE PARAMETERS CHANGED */ 414 *asc = 0x2A; 415 *ascq = 0x01; 416 break; 417 case CTL_UA_LOG_CHANGE: 418 /* 2Ah/02h LOG PARAMETERS CHANGED */ 419 *asc = 0x2A; 420 *ascq = 0x02; 421 break; 422 case CTL_UA_INQ_CHANGE: 423 /* 3Fh/03h INQUIRY DATA HAS CHANGED */ 424 *asc = 0x3F; 425 *ascq = 0x03; 426 break; 427 case CTL_UA_RES_PREEMPT: 428 /* 2Ah/03h RESERVATIONS PREEMPTED */ 429 *asc = 0x2A; 430 *ascq = 0x03; 431 break; 432 case CTL_UA_RES_RELEASE: 433 /* 2Ah/04h RESERVATIONS RELEASED */ 434 *asc = 0x2A; 435 *ascq = 0x04; 436 break; 437 case CTL_UA_REG_PREEMPT: 438 /* 2Ah/05h REGISTRATIONS PREEMPTED */ 439 *asc = 0x2A; 440 *ascq = 0x05; 441 break; 442 case CTL_UA_ASYM_ACC_CHANGE: 443 /* 2Ah/06h ASYMMETRIC ACCESS STATE CHANGED */ 444 *asc = 0x2A; 445 *ascq = 0x06; 446 break; 447 case CTL_UA_CAPACITY_CHANGE: 448 /* 2Ah/09h CAPACITY DATA HAS CHANGED */ 449 *asc = 0x2A; 450 *ascq = 0x09; 451 break; 452 case CTL_UA_THIN_PROV_THRES: 453 /* 38h/07h THIN PROVISIONING SOFT THRESHOLD REACHED */ 454 *asc = 0x38; 455 *ascq = 0x07; 456 *info = lun->ua_tpt_info; 457 break; 458 case CTL_UA_MEDIUM_CHANGE: 459 /* 28h/00h NOT READY TO READY CHANGE, MEDIUM MAY HAVE CHANGED */ 460 *asc = 0x28; 461 *ascq = 0x00; 462 break; 463 case CTL_UA_IE: 464 /* Informational exception */ 465 *asc = lun->ie_asc; 466 *ascq = lun->ie_ascq; 467 break; 468 default: 469 panic("%s: Unknown UA %x", __func__, ua_to_build); 470 } 471} 472 473ctl_ua_type 474ctl_build_qae(struct ctl_lun *lun, uint32_t initidx, uint8_t *resp) 475{ 476 ctl_ua_type ua; 477 ctl_ua_type ua_to_build, ua_to_clear; 478 uint8_t *info; 479 int asc, ascq; 480 uint32_t p, i; 481 482 mtx_assert(&lun->lun_lock, MA_OWNED); 483 p = initidx / CTL_MAX_INIT_PER_PORT; 484 i = initidx % CTL_MAX_INIT_PER_PORT; 485 if (lun->pending_ua[p] == NULL) 486 ua = CTL_UA_POWERON; 487 else 488 ua = lun->pending_ua[p][i]; 489 if (ua == CTL_UA_NONE) 490 return (CTL_UA_NONE); 491 492 ua_to_build = (1 << (ffs(ua) - 1)); 493 ua_to_clear = ua_to_build; 494 info = NULL; 495 ctl_ua_to_acsq(lun, ua_to_build, &asc, &ascq, &ua_to_clear, &info); 496 497 resp[0] = SSD_KEY_UNIT_ATTENTION; 498 if (ua_to_build == ua) 499 resp[0] |= 0x10; 500 else 501 resp[0] |= 0x20; 502 resp[1] = asc; 503 resp[2] = ascq; 504 return (ua); 505} 506 507ctl_ua_type 508ctl_build_ua(struct ctl_lun *lun, uint32_t initidx, 509 struct scsi_sense_data *sense, scsi_sense_data_type sense_format) 510{ 511 ctl_ua_type *ua; 512 ctl_ua_type ua_to_build, ua_to_clear; 513 uint8_t *info; 514 int asc, ascq; 515 uint32_t p, i; 516 517 mtx_assert(&lun->lun_lock, MA_OWNED); 518 p = initidx / CTL_MAX_INIT_PER_PORT; 519 if ((ua = lun->pending_ua[p]) == NULL) { 520 mtx_unlock(&lun->lun_lock); 521 ua = malloc(sizeof(ctl_ua_type) * CTL_MAX_INIT_PER_PORT, 522 M_CTL, M_WAITOK); 523 mtx_lock(&lun->lun_lock); 524 if (lun->pending_ua[p] == NULL) { 525 lun->pending_ua[p] = ua; 526 for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++) 527 ua[i] = CTL_UA_POWERON; 528 } else { 529 free(ua, M_CTL); 530 ua = lun->pending_ua[p]; 531 } 532 } 533 i = initidx % CTL_MAX_INIT_PER_PORT; 534 if (ua[i] == CTL_UA_NONE) 535 return (CTL_UA_NONE); 536 537 ua_to_build = (1 << (ffs(ua[i]) - 1)); 538 ua_to_clear = ua_to_build; 539 info = NULL; 540 ctl_ua_to_acsq(lun, ua_to_build, &asc, &ascq, &ua_to_clear, &info); 541 542 ctl_set_sense_data(sense, lun, sense_format, /*current_error*/ 1, 543 /*sense_key*/ SSD_KEY_UNIT_ATTENTION, asc, ascq, 544 ((info != NULL) ? SSD_ELEM_INFO : SSD_ELEM_SKIP), 8, info, 545 SSD_ELEM_NONE); 546 547 /* We're reporting this UA, so clear it */ 548 ua[i] &= ~ua_to_clear; 549 550 return (ua_to_build); 551} 552 553void 554ctl_set_overlapped_cmd(struct ctl_scsiio *ctsio) 555{ 556 /* OVERLAPPED COMMANDS ATTEMPTED */ 557 ctl_set_sense(ctsio, 558 /*current_error*/ 1, 559 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 560 /*asc*/ 0x4E, 561 /*ascq*/ 0x00, 562 SSD_ELEM_NONE); 563} 564 565void 566ctl_set_overlapped_tag(struct ctl_scsiio *ctsio, uint8_t tag) 567{ 568 /* TAGGED OVERLAPPED COMMANDS (NN = QUEUE TAG) */ 569 ctl_set_sense(ctsio, 570 /*current_error*/ 1, 571 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 572 /*asc*/ 0x4D, 573 /*ascq*/ tag, 574 SSD_ELEM_NONE); 575} 576 577/* 578 * Tell the user that there was a problem with the command or data he sent. 579 */ 580void 581ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command, 582 int field, int bit_valid, int bit) 583{ 584 uint8_t sks[3]; 585 int asc; 586 587 if (command != 0) { 588 /* "Invalid field in CDB" */ 589 asc = 0x24; 590 } else { 591 /* "Invalid field in parameter list" */ 592 asc = 0x26; 593 } 594 595 if (sks_valid) { 596 sks[0] = SSD_SCS_VALID; 597 if (command) 598 sks[0] |= SSD_FIELDPTR_CMD; 599 scsi_ulto2b(field, &sks[1]); 600 601 if (bit_valid) 602 sks[0] |= SSD_BITPTR_VALID | bit; 603 } 604 605 ctl_set_sense(ctsio, 606 /*current_error*/ 1, 607 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 608 asc, 609 /*ascq*/ 0x00, 610 /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP, 611 /*size*/ sizeof(sks), 612 /*data*/ sks, 613 SSD_ELEM_NONE); 614} 615 616void 617ctl_set_invalid_opcode(struct ctl_scsiio *ctsio) 618{ 619 uint8_t sks[3]; 620 621 sks[0] = SSD_SCS_VALID | SSD_FIELDPTR_CMD; 622 scsi_ulto2b(0, &sks[1]); 623 624 /* "Invalid command operation code" */ 625 ctl_set_sense(ctsio, 626 /*current_error*/ 1, 627 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 628 /*asc*/ 0x20, 629 /*ascq*/ 0x00, 630 /*type*/ SSD_ELEM_SKS, 631 /*size*/ sizeof(sks), 632 /*data*/ sks, 633 SSD_ELEM_NONE); 634} 635 636void 637ctl_set_param_len_error(struct ctl_scsiio *ctsio) 638{ 639 /* "Parameter list length error" */ 640 ctl_set_sense(ctsio, 641 /*current_error*/ 1, 642 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 643 /*asc*/ 0x1a, 644 /*ascq*/ 0x00, 645 SSD_ELEM_NONE); 646} 647 648void 649ctl_set_already_locked(struct ctl_scsiio *ctsio) 650{ 651 /* Vendor unique "Somebody already is locked" */ 652 ctl_set_sense(ctsio, 653 /*current_error*/ 1, 654 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 655 /*asc*/ 0x81, 656 /*ascq*/ 0x00, 657 SSD_ELEM_NONE); 658} 659 660void 661ctl_set_unsupported_lun(struct ctl_scsiio *ctsio) 662{ 663 /* "Logical unit not supported" */ 664 ctl_set_sense(ctsio, 665 /*current_error*/ 1, 666 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 667 /*asc*/ 0x25, 668 /*ascq*/ 0x00, 669 SSD_ELEM_NONE); 670} 671 672void 673ctl_set_internal_failure(struct ctl_scsiio *ctsio, int sks_valid, 674 uint16_t retry_count) 675{ 676 uint8_t sks[3]; 677 678 if (sks_valid) { 679 sks[0] = SSD_SCS_VALID; 680 sks[1] = (retry_count >> 8) & 0xff; 681 sks[2] = retry_count & 0xff; 682 } 683 684 /* "Internal target failure" */ 685 ctl_set_sense(ctsio, 686 /*current_error*/ 1, 687 /*sense_key*/ SSD_KEY_HARDWARE_ERROR, 688 /*asc*/ 0x44, 689 /*ascq*/ 0x00, 690 /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP, 691 /*size*/ sizeof(sks), 692 /*data*/ sks, 693 SSD_ELEM_NONE); 694} 695 696void 697ctl_set_medium_error(struct ctl_scsiio *ctsio, int read) 698{ 699 if (read) { 700 /* "Unrecovered read error" */ 701 ctl_set_sense(ctsio, 702 /*current_error*/ 1, 703 /*sense_key*/ SSD_KEY_MEDIUM_ERROR, 704 /*asc*/ 0x11, 705 /*ascq*/ 0x00, 706 SSD_ELEM_NONE); 707 } else { 708 /* "Write error - auto reallocation failed" */ 709 ctl_set_sense(ctsio, 710 /*current_error*/ 1, 711 /*sense_key*/ SSD_KEY_MEDIUM_ERROR, 712 /*asc*/ 0x0C, 713 /*ascq*/ 0x02, 714 SSD_ELEM_NONE); 715 } 716} 717 718void 719ctl_set_aborted(struct ctl_scsiio *ctsio) 720{ 721 ctl_set_sense(ctsio, 722 /*current_error*/ 1, 723 /*sense_key*/ SSD_KEY_ABORTED_COMMAND, 724 /*asc*/ 0x45, 725 /*ascq*/ 0x00, 726 SSD_ELEM_NONE); 727} 728 729void 730ctl_set_lba_out_of_range(struct ctl_scsiio *ctsio) 731{ 732 /* "Logical block address out of range" */ 733 ctl_set_sense(ctsio, 734 /*current_error*/ 1, 735 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 736 /*asc*/ 0x21, 737 /*ascq*/ 0x00, 738 SSD_ELEM_NONE); 739} 740 741void 742ctl_set_lun_stopped(struct ctl_scsiio *ctsio) 743{ 744 /* "Logical unit not ready, initializing cmd. required" */ 745 ctl_set_sense(ctsio, 746 /*current_error*/ 1, 747 /*sense_key*/ SSD_KEY_NOT_READY, 748 /*asc*/ 0x04, 749 /*ascq*/ 0x02, 750 SSD_ELEM_NONE); 751} 752 753void 754ctl_set_lun_int_reqd(struct ctl_scsiio *ctsio) 755{ 756 /* "Logical unit not ready, manual intervention required" */ 757 ctl_set_sense(ctsio, 758 /*current_error*/ 1, 759 /*sense_key*/ SSD_KEY_NOT_READY, 760 /*asc*/ 0x04, 761 /*ascq*/ 0x03, 762 SSD_ELEM_NONE); 763} 764 765void 766ctl_set_lun_ejected(struct ctl_scsiio *ctsio) 767{ 768 /* "Medium not present - tray open" */ 769 ctl_set_sense(ctsio, 770 /*current_error*/ 1, 771 /*sense_key*/ SSD_KEY_NOT_READY, 772 /*asc*/ 0x3A, 773 /*ascq*/ 0x02, 774 SSD_ELEM_NONE); 775} 776 777void 778ctl_set_lun_no_media(struct ctl_scsiio *ctsio) 779{ 780 /* "Medium not present - tray closed" */ 781 ctl_set_sense(ctsio, 782 /*current_error*/ 1, 783 /*sense_key*/ SSD_KEY_NOT_READY, 784 /*asc*/ 0x3A, 785 /*ascq*/ 0x01, 786 SSD_ELEM_NONE); 787} 788 789void 790ctl_set_illegal_pr_release(struct ctl_scsiio *ctsio) 791{ 792 /* "Invalid release of persistent reservation" */ 793 ctl_set_sense(ctsio, 794 /*current_error*/ 1, 795 /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST, 796 /*asc*/ 0x26, 797 /*ascq*/ 0x04, 798 SSD_ELEM_NONE); 799} 800 801void 802ctl_set_lun_transit(struct ctl_scsiio *ctsio) 803{ 804 /* "Logical unit not ready, asymmetric access state transition" */ 805 ctl_set_sense(ctsio, 806 /*current_error*/ 1, 807 /*sense_key*/ SSD_KEY_NOT_READY, 808 /*asc*/ 0x04, 809 /*ascq*/ 0x0a, 810 SSD_ELEM_NONE); 811} 812 813void 814ctl_set_lun_standby(struct ctl_scsiio *ctsio) 815{ 816 /* "Logical unit not ready, target port in standby state" */ 817 ctl_set_sense(ctsio, 818 /*current_error*/ 1, 819 /*sense_key*/ SSD_KEY_NOT_READY, 820 /*asc*/ 0x04, 821 /*ascq*/ 0x0b, 822 SSD_ELEM_NONE); 823} 824 825void 826ctl_set_lun_unavail(struct ctl_scsiio *ctsio) 827{ 828 /* "Logical unit not ready, target port in unavailable state" */ 829 ctl_set_sense(ctsio, 830 /*current_error*/ 1, 831 /*sense_key*/ SSD_KEY_NOT_READY, 832 /*asc*/ 0x04, 833 /*ascq*/ 0x0c, 834 SSD_ELEM_NONE); 835} 836 837void 838ctl_set_medium_format_corrupted(struct ctl_scsiio *ctsio) 839{ 840 /* "Medium format corrupted" */ 841 ctl_set_sense(ctsio, 842 /*current_error*/ 1, 843 /*sense_key*/ SSD_KEY_MEDIUM_ERROR, 844 /*asc*/ 0x31, 845 /*ascq*/ 0x00, 846 SSD_ELEM_NONE); 847} 848 849void 850ctl_set_medium_magazine_inaccessible(struct ctl_scsiio *ctsio) 851{ 852 /* "Medium magazine not accessible" */ 853 ctl_set_sense(ctsio, 854 /*current_error*/ 1, 855 /*sense_key*/ SSD_KEY_NOT_READY, 856 /*asc*/ 0x3b, 857 /*ascq*/ 0x11, 858 SSD_ELEM_NONE); 859} 860 861void 862ctl_set_data_phase_error(struct ctl_scsiio *ctsio) 863{ 864 /* "Data phase error" */ 865 ctl_set_sense(ctsio, 866 /*current_error*/ 1, 867 /*sense_key*/ SSD_KEY_NOT_READY, 868 /*asc*/ 0x4b, 869 /*ascq*/ 0x00, 870 SSD_ELEM_NONE); 871} 872 873void 874ctl_set_reservation_conflict(struct ctl_scsiio *ctsio) 875{ 876 struct scsi_sense_data *sense; 877 878 sense = &ctsio->sense_data; 879 memset(sense, 0, sizeof(*sense)); 880 ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT; 881 ctsio->sense_len = 0; 882 ctsio->io_hdr.status = CTL_SCSI_ERROR; 883} 884 885void 886ctl_set_queue_full(struct ctl_scsiio *ctsio) 887{ 888 struct scsi_sense_data *sense; 889 890 sense = &ctsio->sense_data; 891 memset(sense, 0, sizeof(*sense)); 892 ctsio->scsi_status = SCSI_STATUS_QUEUE_FULL; 893 ctsio->sense_len = 0; 894 ctsio->io_hdr.status = CTL_SCSI_ERROR; 895} 896 897void 898ctl_set_busy(struct ctl_scsiio *ctsio) 899{ 900 struct scsi_sense_data *sense; 901 902 sense = &ctsio->sense_data; 903 memset(sense, 0, sizeof(*sense)); 904 ctsio->scsi_status = SCSI_STATUS_BUSY; 905 ctsio->sense_len = 0; 906 ctsio->io_hdr.status = CTL_SCSI_ERROR; 907} 908 909void 910ctl_set_task_aborted(struct ctl_scsiio *ctsio) 911{ 912 struct scsi_sense_data *sense; 913 914 sense = &ctsio->sense_data; 915 memset(sense, 0, sizeof(*sense)); 916 ctsio->scsi_status = SCSI_STATUS_TASK_ABORTED; 917 ctsio->sense_len = 0; 918 ctsio->io_hdr.status = CTL_CMD_ABORTED; 919} 920 921void 922ctl_set_hw_write_protected(struct ctl_scsiio *ctsio) 923{ 924 /* "Hardware write protected" */ 925 ctl_set_sense(ctsio, 926 /*current_error*/ 1, 927 /*sense_key*/ SSD_KEY_DATA_PROTECT, 928 /*asc*/ 0x27, 929 /*ascq*/ 0x01, 930 SSD_ELEM_NONE); 931} 932 933void 934ctl_set_space_alloc_fail(struct ctl_scsiio *ctsio) 935{ 936 /* "Space allocation failed write protect" */ 937 ctl_set_sense(ctsio, 938 /*current_error*/ 1, 939 /*sense_key*/ SSD_KEY_DATA_PROTECT, 940 /*asc*/ 0x27, 941 /*ascq*/ 0x07, 942 SSD_ELEM_NONE); 943} 944 945void 946ctl_set_success(struct ctl_scsiio *ctsio) 947{ 948 struct scsi_sense_data *sense; 949 950 sense = &ctsio->sense_data; 951 memset(sense, 0, sizeof(*sense)); 952 ctsio->scsi_status = SCSI_STATUS_OK; 953 ctsio->sense_len = 0; 954 ctsio->io_hdr.status = CTL_SUCCESS; 955} 956