]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - sys/cam/ctl/ctl_error.c
MFC r232604:
[FreeBSD/stable/9.git] / sys / cam / ctl / ctl_error.c
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 <machine/stdarg.h>
53
54 #include <cam/scsi/scsi_all.h>
55 #include <cam/scsi/scsi_da.h>
56 #include <cam/ctl/ctl_io.h>
57 #include <cam/ctl/ctl.h>
58 #include <cam/ctl/ctl_frontend.h>
59 #include <cam/ctl/ctl_frontend_internal.h>
60 #include <cam/ctl/ctl_backend.h>
61 #include <cam/ctl/ctl_ioctl.h>
62 #include <cam/ctl/ctl_error.h>
63 #include <cam/ctl/ctl_ha.h>
64 #include <cam/ctl/ctl_private.h>
65
66 void
67 ctl_set_sense_data_va(struct scsi_sense_data *sense_data, void *lunptr,
68                       scsi_sense_data_type sense_format, int current_error,
69                       int sense_key, int asc, int ascq, va_list ap) 
70 {
71         struct ctl_lun *lun;
72
73         lun = (struct ctl_lun *)lunptr;
74
75         /*
76          * Determine whether to return fixed or descriptor format sense
77          * data.
78          */
79         if (sense_format == SSD_TYPE_NONE) {
80                 /*
81                  * If the format isn't specified, we only return descriptor
82                  * sense if the LUN exists and descriptor sense is turned
83                  * on for that LUN.
84                  */
85                 if ((lun != NULL)
86                  && (lun->flags & CTL_LUN_SENSE_DESC))
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
96 void
97 ctl_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
109 void
110 ctl_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  */
145 void
146 ctl_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  */
226 void
227 ctl_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
357 void
358 ctl_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
368 ctl_ua_type
369 ctl_build_ua(ctl_ua_type ua_type, struct scsi_sense_data *sense,
370              scsi_sense_data_type sense_format)
371 {
372         ctl_ua_type ua_to_build;
373         int i, asc, ascq;
374
375         if (ua_type == CTL_UA_NONE)
376                 return (ua_type);
377
378         ua_to_build = CTL_UA_NONE;
379
380         for (i = 0; i < (sizeof(ua_type) * 8); i++) {
381                 if (ua_type & (1 << i)) {
382                         ua_to_build = 1 << i;
383                         break;
384                 }
385         }
386
387         switch (ua_to_build) {
388         case CTL_UA_POWERON:
389                 /* 29h/01h  POWER ON OCCURRED */
390                 asc = 0x29;
391                 ascq = 0x01;
392                 break;
393         case CTL_UA_BUS_RESET:
394                 /* 29h/02h  SCSI BUS RESET OCCURRED */
395                 asc = 0x29;
396                 ascq = 0x02;
397                 break;
398         case CTL_UA_TARG_RESET:
399                 /* 29h/03h  BUS DEVICE RESET FUNCTION OCCURRED*/
400                 asc = 0x29;
401                 ascq = 0x03;
402                 break;
403         case CTL_UA_LUN_RESET:
404                 /* 29h/00h  POWER ON, RESET, OR BUS DEVICE RESET OCCURRED */
405                 /*
406                  * Since we don't have a specific ASC/ASCQ pair for a LUN
407                  * reset, just return the generic reset code.
408                  */
409                 asc = 0x29;
410                 ascq = 0x00;
411                 break;
412         case CTL_UA_LUN_CHANGE:
413                 /* 3Fh/0Eh  REPORTED LUNS DATA HAS CHANGED */
414                 asc = 0x3F;
415                 ascq = 0x0E;
416                 break;
417         case CTL_UA_MODE_CHANGE:
418                 /* 2Ah/01h  MODE PARAMETERS CHANGED */
419                 asc = 0x2A;
420                 ascq = 0x01;
421                 break;
422         case CTL_UA_LOG_CHANGE:
423                 /* 2Ah/02h  LOG PARAMETERS CHANGED */
424                 asc = 0x2A;
425                 ascq = 0x02;
426                 break;
427         case CTL_UA_LVD:
428                 /* 29h/06h  TRANSCEIVER MODE CHANGED TO LVD */
429                 asc = 0x29;
430                 ascq = 0x06;
431                 break;
432         case CTL_UA_SE:
433                 /* 29h/05h  TRANSCEIVER MODE CHANGED TO SINGLE-ENDED */
434                 asc = 0x29;
435                 ascq = 0x05;
436                 break;
437         case CTL_UA_RES_PREEMPT:
438                 /* 2Ah/03h  RESERVATIONS PREEMPTED */
439                 asc = 0x2A;
440                 ascq = 0x03;
441                 break;
442         case CTL_UA_RES_RELEASE:
443                 /* 2Ah/04h  RESERVATIONS RELEASED */
444                 asc = 0x2A;
445                 ascq = 0x04;
446                 break;
447         case CTL_UA_REG_PREEMPT:
448                 /* 2Ah/05h  REGISTRATIONS PREEMPTED */
449                 asc = 0x2A;
450                 ascq = 0x05;
451                 break;
452         case CTL_UA_ASYM_ACC_CHANGE:
453                 /* 2Ah/06n  ASYMMETRIC ACCESS STATE CHANGED */
454                 asc = 0x2A;
455                 ascq = 0x06;
456                 break;
457         case CTL_UA_CAPACITY_CHANGED:
458                 /* 2Ah/09n  CAPACITY DATA HAS CHANGED */
459                 asc = 0x2A;
460                 ascq = 0x09;
461                 break;
462         default:
463                 ua_to_build = CTL_UA_NONE;
464                 return (ua_to_build);
465                 break; /* NOTREACHED */
466         }
467
468         ctl_set_sense_data(sense,
469                            /*lun*/ NULL,
470                            sense_format,
471                            /*current_error*/ 1,
472                            /*sense_key*/ SSD_KEY_UNIT_ATTENTION,
473                            asc,
474                            ascq,
475                            SSD_ELEM_NONE);
476
477         return (ua_to_build);
478 }
479
480 void
481 ctl_set_overlapped_cmd(struct ctl_scsiio *ctsio)
482 {
483         /* OVERLAPPED COMMANDS ATTEMPTED */
484         ctl_set_sense(ctsio,
485                       /*current_error*/ 1,
486                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
487                       /*asc*/ 0x4E,
488                       /*ascq*/ 0x00,
489                       SSD_ELEM_NONE);
490 }
491
492 void
493 ctl_set_overlapped_tag(struct ctl_scsiio *ctsio, uint8_t tag)
494 {
495         /* TAGGED OVERLAPPED COMMANDS (NN = QUEUE TAG) */
496         ctl_set_sense(ctsio,
497                       /*current_error*/ 1,
498                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
499                       /*asc*/ 0x4D,
500                       /*ascq*/ tag,
501                       SSD_ELEM_NONE);
502 }
503
504 /*
505  * Tell the user that there was a problem with the command or data he sent.
506  */
507 void
508 ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command,
509                       int field, int bit_valid, int bit)
510 {
511         uint8_t sks[3];
512         int asc;
513
514         if (command != 0) {
515                 /* "Invalid field in CDB" */
516                 asc = 0x24;
517         } else {
518                 /* "Invalid field in parameter list" */
519                 asc = 0x26;
520         }
521
522         if (sks_valid) {
523                 sks[0] = SSD_SCS_VALID;
524                 if (command)
525                         sks[0] |= SSD_FIELDPTR_CMD;
526                 scsi_ulto2b(field, &sks[1]);
527
528                 if (bit_valid)
529                         sks[0] |= SSD_BITPTR_VALID | bit;
530         }
531
532         ctl_set_sense(ctsio,
533                       /*current_error*/ 1,
534                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
535                       asc,
536                       /*ascq*/ 0x00,
537                       /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP,
538                       /*size*/ sizeof(sks),
539                       /*data*/ sks,
540                       SSD_ELEM_NONE);
541 }
542
543 void
544 ctl_set_invalid_opcode(struct ctl_scsiio *ctsio)
545 {
546         struct scsi_sense_data *sense;
547         uint8_t sks[3];
548
549         sense = &ctsio->sense_data;
550
551         sks[0] = SSD_SCS_VALID | SSD_FIELDPTR_CMD;
552         scsi_ulto2b(0, &sks[1]);
553
554         /* "Invalid command operation code" */
555         ctl_set_sense(ctsio,
556                       /*current_error*/ 1,
557                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
558                       /*asc*/ 0x20,
559                       /*ascq*/ 0x00,
560                       /*type*/ SSD_ELEM_SKS,
561                       /*size*/ sizeof(sks),
562                       /*data*/ sks,
563                       SSD_ELEM_NONE);
564 }
565
566 void
567 ctl_set_param_len_error(struct ctl_scsiio *ctsio)
568 {
569         /* "Parameter list length error" */
570         ctl_set_sense(ctsio,
571                       /*current_error*/ 1,
572                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
573                       /*asc*/ 0x1a,
574                       /*ascq*/ 0x00,
575                       SSD_ELEM_NONE);
576 }
577
578 void
579 ctl_set_already_locked(struct ctl_scsiio *ctsio)
580 {
581         /* Vendor unique "Somebody already is locked" */
582         ctl_set_sense(ctsio,
583                       /*current_error*/ 1,
584                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
585                       /*asc*/ 0x81,
586                       /*ascq*/ 0x00,
587                       SSD_ELEM_NONE);
588 }
589
590 void
591 ctl_set_unsupported_lun(struct ctl_scsiio *ctsio)
592 {
593         /* "Logical unit not supported" */
594         ctl_set_sense(ctsio,
595                       /*current_error*/ 1,
596                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
597                       /*asc*/ 0x25,
598                       /*ascq*/ 0x00,
599                       SSD_ELEM_NONE);
600 }
601
602 void
603 ctl_set_internal_failure(struct ctl_scsiio *ctsio, int sks_valid,
604                          uint16_t retry_count)
605 {
606         uint8_t sks[3];
607
608         if (sks_valid) {
609                 sks[0] = SSD_SCS_VALID;
610                 sks[1] = (retry_count >> 8) & 0xff;
611                 sks[2] = retry_count & 0xff;
612         }
613
614         /* "Internal target failure" */
615         ctl_set_sense(ctsio,
616                       /*current_error*/ 1,
617                       /*sense_key*/ SSD_KEY_HARDWARE_ERROR,
618                       /*asc*/ 0x44,
619                       /*ascq*/ 0x00,
620                       /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP,
621                       /*size*/ sizeof(sks),
622                       /*data*/ sks,
623                       SSD_ELEM_NONE);
624 }
625
626 void
627 ctl_set_medium_error(struct ctl_scsiio *ctsio)
628 {
629         if ((ctsio->io_hdr.flags & CTL_FLAG_DATA_MASK) == CTL_FLAG_DATA_IN) {
630                 /* "Unrecovered read error" */
631                 ctl_set_sense(ctsio,
632                               /*current_error*/ 1,
633                               /*sense_key*/ SSD_KEY_MEDIUM_ERROR,
634                               /*asc*/ 0x11,
635                               /*ascq*/ 0x00,
636                               SSD_ELEM_NONE);
637         } else {
638                 /* "Write error - auto reallocation failed" */
639                 ctl_set_sense(ctsio,
640                               /*current_error*/ 1,
641                               /*sense_key*/ SSD_KEY_MEDIUM_ERROR,
642                               /*asc*/ 0x0C,
643                               /*ascq*/ 0x02,
644                               SSD_ELEM_NONE);
645         }
646 }
647
648 void
649 ctl_set_aborted(struct ctl_scsiio *ctsio)
650 {
651         ctl_set_sense(ctsio,
652                       /*current_error*/ 1,
653                       /*sense_key*/ SSD_KEY_ABORTED_COMMAND,
654                       /*asc*/ 0x45,
655                       /*ascq*/ 0x00,
656                       SSD_ELEM_NONE);
657 }
658
659 void
660 ctl_set_lba_out_of_range(struct ctl_scsiio *ctsio)
661 {
662         /* "Logical block address out of range" */
663         ctl_set_sense(ctsio,
664                       /*current_error*/ 1,
665                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
666                       /*asc*/ 0x21,
667                       /*ascq*/ 0x00,
668                       SSD_ELEM_NONE);
669 }
670
671 void
672 ctl_set_lun_stopped(struct ctl_scsiio *ctsio)
673 {
674         /* "Logical unit not ready, initializing cmd. required" */
675         ctl_set_sense(ctsio,
676                       /*current_error*/ 1,
677                       /*sense_key*/ SSD_KEY_NOT_READY,
678                       /*asc*/ 0x04,
679                       /*ascq*/ 0x02,
680                       SSD_ELEM_NONE);
681 }
682
683 void
684 ctl_set_lun_not_ready(struct ctl_scsiio *ctsio)
685 {
686         /* "Logical unit not ready, manual intervention required" */
687         ctl_set_sense(ctsio,
688                       /*current_error*/ 1,
689                       /*sense_key*/ SSD_KEY_NOT_READY,
690                       /*asc*/ 0x04,
691                       /*ascq*/ 0x05,
692                       SSD_ELEM_NONE);
693 }
694
695 void
696 ctl_set_illegal_pr_release(struct ctl_scsiio *ctsio)
697 {
698         /* "Invalid release of persistent reservation" */
699         ctl_set_sense(ctsio,
700                       /*current_error*/ 1,
701                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
702                       /*asc*/ 0x26,
703                       /*ascq*/ 0x04,
704                       SSD_ELEM_NONE);
705 }
706
707 void
708 ctl_set_lun_standby(struct ctl_scsiio *ctsio)
709 {
710         /* "Logical unit not ready, target port in standby state" */
711         ctl_set_sense(ctsio,
712                       /*current_error*/ 1,
713                       /*sense_key*/ SSD_KEY_NOT_READY,
714                       /*asc*/ 0x04,
715                       /*ascq*/ 0x0b,
716                       SSD_ELEM_NONE);
717 }
718
719 void
720 ctl_set_medium_format_corrupted(struct ctl_scsiio *ctsio)
721 {
722         /* "Medium format corrupted" */
723         ctl_set_sense(ctsio,
724                       /*current_error*/ 1,
725                       /*sense_key*/ SSD_KEY_MEDIUM_ERROR,
726                       /*asc*/ 0x31,
727                       /*ascq*/ 0x00,
728                       SSD_ELEM_NONE);
729 }
730
731 void
732 ctl_set_medium_magazine_inaccessible(struct ctl_scsiio *ctsio)
733 {
734         /* "Medium magazine not accessible" */
735         ctl_set_sense(ctsio,
736                       /*current_error*/ 1,
737                       /*sense_key*/ SSD_KEY_NOT_READY,
738                       /*asc*/ 0x3b,
739                       /*ascq*/ 0x11,
740                       SSD_ELEM_NONE);
741 }
742
743 void
744 ctl_set_data_phase_error(struct ctl_scsiio *ctsio)
745 {
746         /* "Data phase error" */
747         ctl_set_sense(ctsio,
748                       /*current_error*/ 1,
749                       /*sense_key*/ SSD_KEY_NOT_READY,
750                       /*asc*/ 0x4b,
751                       /*ascq*/ 0x00,
752                       SSD_ELEM_NONE);
753 }
754
755 void
756 ctl_set_reservation_conflict(struct ctl_scsiio *ctsio)
757 {
758         struct scsi_sense_data *sense;
759
760         sense = &ctsio->sense_data;
761         memset(sense, 0, sizeof(*sense));
762         ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
763         ctsio->sense_len = 0;
764         ctsio->io_hdr.status = CTL_SCSI_ERROR;
765 }
766
767 void
768 ctl_set_queue_full(struct ctl_scsiio *ctsio)
769 {
770         struct scsi_sense_data *sense;
771
772         sense = &ctsio->sense_data;
773         memset(sense, 0, sizeof(*sense));
774         ctsio->scsi_status = SCSI_STATUS_QUEUE_FULL;
775         ctsio->sense_len = 0;
776         ctsio->io_hdr.status = CTL_SCSI_ERROR;
777 }
778
779 void
780 ctl_set_busy(struct ctl_scsiio *ctsio)
781 {
782         struct scsi_sense_data *sense;
783
784         sense = &ctsio->sense_data;
785         memset(sense, 0, sizeof(*sense));
786         ctsio->scsi_status = SCSI_STATUS_BUSY;
787         ctsio->sense_len = 0;
788         ctsio->io_hdr.status = CTL_SCSI_ERROR;
789 }
790
791 void
792 ctl_set_success(struct ctl_scsiio *ctsio)
793 {
794         struct scsi_sense_data *sense;
795
796         sense = &ctsio->sense_data;
797         memset(sense, 0, sizeof(*sense));
798         ctsio->scsi_status = SCSI_STATUS_OK;
799         ctsio->sense_len = 0;
800         ctsio->io_hdr.status = CTL_SUCCESS;
801 }