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