]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - sys/cam/ctl/ctl_error.c
MFC r310366: Add support for SITUA bit in Logical Block Provisioning mode page.
[FreeBSD/stable/10.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  * 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$");
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
67 void
68 ctl_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
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                            (sense_src->error_code & SSD_ERRCODE_VALID) ?
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 static void
369 ctl_ua_to_ascq(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
473 ctl_ua_type
474 ctl_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_ascq(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
507 ctl_ua_type
508 ctl_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         mtx_assert(&lun->ctl_softc->ctl_lock, MA_NOTOWNED);
519         p = initidx / CTL_MAX_INIT_PER_PORT;
520         if ((ua = lun->pending_ua[p]) == NULL) {
521                 mtx_unlock(&lun->lun_lock);
522                 ua = malloc(sizeof(ctl_ua_type) * CTL_MAX_INIT_PER_PORT,
523                     M_CTL, M_WAITOK);
524                 mtx_lock(&lun->lun_lock);
525                 if (lun->pending_ua[p] == NULL) {
526                         lun->pending_ua[p] = ua;
527                         for (i = 0; i < CTL_MAX_INIT_PER_PORT; i++)
528                                 ua[i] = CTL_UA_POWERON;
529                 } else {
530                         free(ua, M_CTL);
531                         ua = lun->pending_ua[p];
532                 }
533         }
534         i = initidx % CTL_MAX_INIT_PER_PORT;
535         if (ua[i] == CTL_UA_NONE)
536                 return (CTL_UA_NONE);
537
538         ua_to_build = (1 << (ffs(ua[i]) - 1));
539         ua_to_clear = ua_to_build;
540         info = NULL;
541         ctl_ua_to_ascq(lun, ua_to_build, &asc, &ascq, &ua_to_clear, &info);
542
543         ctl_set_sense_data(sense, lun, sense_format, /*current_error*/ 1,
544             /*sense_key*/ SSD_KEY_UNIT_ATTENTION, asc, ascq,
545             ((info != NULL) ? SSD_ELEM_INFO : SSD_ELEM_SKIP), 8, info,
546             SSD_ELEM_NONE);
547
548         /* We're reporting this UA, so clear it */
549         ua[i] &= ~ua_to_clear;
550
551         if (ua_to_build == CTL_UA_LUN_CHANGE) {
552                 mtx_unlock(&lun->lun_lock);
553                 mtx_lock(&lun->ctl_softc->ctl_lock);
554                 ctl_clr_ua_allluns(lun->ctl_softc, initidx, ua_to_build);
555                 mtx_unlock(&lun->ctl_softc->ctl_lock);
556                 mtx_lock(&lun->lun_lock);
557         } else if (ua_to_build == CTL_UA_THIN_PROV_THRES &&
558             (lun->MODE_LBP.main.flags & SLBPP_SITUA) != 0) {
559                 ctl_clr_ua_all(lun, -1, ua_to_build);
560         }
561
562         return (ua_to_build);
563 }
564
565 void
566 ctl_set_overlapped_cmd(struct ctl_scsiio *ctsio)
567 {
568         /* OVERLAPPED COMMANDS ATTEMPTED */
569         ctl_set_sense(ctsio,
570                       /*current_error*/ 1,
571                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
572                       /*asc*/ 0x4E,
573                       /*ascq*/ 0x00,
574                       SSD_ELEM_NONE);
575 }
576
577 void
578 ctl_set_overlapped_tag(struct ctl_scsiio *ctsio, uint8_t tag)
579 {
580         /* TAGGED OVERLAPPED COMMANDS (NN = QUEUE TAG) */
581         ctl_set_sense(ctsio,
582                       /*current_error*/ 1,
583                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
584                       /*asc*/ 0x4D,
585                       /*ascq*/ tag,
586                       SSD_ELEM_NONE);
587 }
588
589 /*
590  * Tell the user that there was a problem with the command or data he sent.
591  */
592 void
593 ctl_set_invalid_field(struct ctl_scsiio *ctsio, int sks_valid, int command,
594                       int field, int bit_valid, int bit)
595 {
596         uint8_t sks[3];
597         int asc;
598
599         if (command != 0) {
600                 /* "Invalid field in CDB" */
601                 asc = 0x24;
602         } else {
603                 /* "Invalid field in parameter list" */
604                 asc = 0x26;
605         }
606
607         if (sks_valid) {
608                 sks[0] = SSD_SCS_VALID;
609                 if (command)
610                         sks[0] |= SSD_FIELDPTR_CMD;
611                 scsi_ulto2b(field, &sks[1]);
612
613                 if (bit_valid)
614                         sks[0] |= SSD_BITPTR_VALID | bit;
615         }
616
617         ctl_set_sense(ctsio,
618                       /*current_error*/ 1,
619                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
620                       asc,
621                       /*ascq*/ 0x00,
622                       /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP,
623                       /*size*/ sizeof(sks),
624                       /*data*/ sks,
625                       SSD_ELEM_NONE);
626 }
627
628 void
629 ctl_set_invalid_opcode(struct ctl_scsiio *ctsio)
630 {
631         uint8_t sks[3];
632
633         sks[0] = SSD_SCS_VALID | SSD_FIELDPTR_CMD;
634         scsi_ulto2b(0, &sks[1]);
635
636         /* "Invalid command operation code" */
637         ctl_set_sense(ctsio,
638                       /*current_error*/ 1,
639                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
640                       /*asc*/ 0x20,
641                       /*ascq*/ 0x00,
642                       /*type*/ SSD_ELEM_SKS,
643                       /*size*/ sizeof(sks),
644                       /*data*/ sks,
645                       SSD_ELEM_NONE);
646 }
647
648 void
649 ctl_set_param_len_error(struct ctl_scsiio *ctsio)
650 {
651         /* "Parameter list length error" */
652         ctl_set_sense(ctsio,
653                       /*current_error*/ 1,
654                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
655                       /*asc*/ 0x1a,
656                       /*ascq*/ 0x00,
657                       SSD_ELEM_NONE);
658 }
659
660 void
661 ctl_set_already_locked(struct ctl_scsiio *ctsio)
662 {
663         /* Vendor unique "Somebody already is locked" */
664         ctl_set_sense(ctsio,
665                       /*current_error*/ 1,
666                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
667                       /*asc*/ 0x81,
668                       /*ascq*/ 0x00,
669                       SSD_ELEM_NONE);
670 }
671
672 void
673 ctl_set_unsupported_lun(struct ctl_scsiio *ctsio)
674 {
675         /* "Logical unit not supported" */
676         ctl_set_sense(ctsio,
677                       /*current_error*/ 1,
678                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
679                       /*asc*/ 0x25,
680                       /*ascq*/ 0x00,
681                       SSD_ELEM_NONE);
682 }
683
684 void
685 ctl_set_internal_failure(struct ctl_scsiio *ctsio, int sks_valid,
686                          uint16_t retry_count)
687 {
688         uint8_t sks[3];
689
690         if (sks_valid) {
691                 sks[0] = SSD_SCS_VALID;
692                 sks[1] = (retry_count >> 8) & 0xff;
693                 sks[2] = retry_count & 0xff;
694         }
695
696         /* "Internal target failure" */
697         ctl_set_sense(ctsio,
698                       /*current_error*/ 1,
699                       /*sense_key*/ SSD_KEY_HARDWARE_ERROR,
700                       /*asc*/ 0x44,
701                       /*ascq*/ 0x00,
702                       /*type*/ (sks_valid != 0) ? SSD_ELEM_SKS : SSD_ELEM_SKIP,
703                       /*size*/ sizeof(sks),
704                       /*data*/ sks,
705                       SSD_ELEM_NONE);
706 }
707
708 void
709 ctl_set_medium_error(struct ctl_scsiio *ctsio, int read)
710 {
711         if (read) {
712                 /* "Unrecovered read error" */
713                 ctl_set_sense(ctsio,
714                               /*current_error*/ 1,
715                               /*sense_key*/ SSD_KEY_MEDIUM_ERROR,
716                               /*asc*/ 0x11,
717                               /*ascq*/ 0x00,
718                               SSD_ELEM_NONE);
719         } else {
720                 /* "Write error - auto reallocation failed" */
721                 ctl_set_sense(ctsio,
722                               /*current_error*/ 1,
723                               /*sense_key*/ SSD_KEY_MEDIUM_ERROR,
724                               /*asc*/ 0x0C,
725                               /*ascq*/ 0x02,
726                               SSD_ELEM_NONE);
727         }
728 }
729
730 void
731 ctl_set_aborted(struct ctl_scsiio *ctsio)
732 {
733         ctl_set_sense(ctsio,
734                       /*current_error*/ 1,
735                       /*sense_key*/ SSD_KEY_ABORTED_COMMAND,
736                       /*asc*/ 0x45,
737                       /*ascq*/ 0x00,
738                       SSD_ELEM_NONE);
739 }
740
741 void
742 ctl_set_lba_out_of_range(struct ctl_scsiio *ctsio, uint64_t lba)
743 {
744         uint8_t info[8];
745
746         scsi_u64to8b(lba, info);
747
748         /* "Logical block address out of range" */
749         ctl_set_sense(ctsio,
750                       /*current_error*/ 1,
751                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
752                       /*asc*/ 0x21,
753                       /*ascq*/ 0x00,
754                       /*type*/ (lba != 0) ? SSD_ELEM_INFO : SSD_ELEM_SKIP,
755                       /*size*/ sizeof(info), /*data*/ &info,
756                       SSD_ELEM_NONE);
757 }
758
759 void
760 ctl_set_lun_stopped(struct ctl_scsiio *ctsio)
761 {
762         /* "Logical unit not ready, initializing cmd. required" */
763         ctl_set_sense(ctsio,
764                       /*current_error*/ 1,
765                       /*sense_key*/ SSD_KEY_NOT_READY,
766                       /*asc*/ 0x04,
767                       /*ascq*/ 0x02,
768                       SSD_ELEM_NONE);
769 }
770
771 void
772 ctl_set_lun_int_reqd(struct ctl_scsiio *ctsio)
773 {
774         /* "Logical unit not ready, manual intervention required" */
775         ctl_set_sense(ctsio,
776                       /*current_error*/ 1,
777                       /*sense_key*/ SSD_KEY_NOT_READY,
778                       /*asc*/ 0x04,
779                       /*ascq*/ 0x03,
780                       SSD_ELEM_NONE);
781 }
782
783 void
784 ctl_set_lun_ejected(struct ctl_scsiio *ctsio)
785 {
786         /* "Medium not present - tray open" */
787         ctl_set_sense(ctsio,
788                       /*current_error*/ 1,
789                       /*sense_key*/ SSD_KEY_NOT_READY,
790                       /*asc*/ 0x3A,
791                       /*ascq*/ 0x02,
792                       SSD_ELEM_NONE);
793 }
794
795 void
796 ctl_set_lun_no_media(struct ctl_scsiio *ctsio)
797 {
798         /* "Medium not present - tray closed" */
799         ctl_set_sense(ctsio,
800                       /*current_error*/ 1,
801                       /*sense_key*/ SSD_KEY_NOT_READY,
802                       /*asc*/ 0x3A,
803                       /*ascq*/ 0x01,
804                       SSD_ELEM_NONE);
805 }
806
807 void
808 ctl_set_illegal_pr_release(struct ctl_scsiio *ctsio)
809 {
810         /* "Invalid release of persistent reservation" */
811         ctl_set_sense(ctsio,
812                       /*current_error*/ 1,
813                       /*sense_key*/ SSD_KEY_ILLEGAL_REQUEST,
814                       /*asc*/ 0x26,
815                       /*ascq*/ 0x04,
816                       SSD_ELEM_NONE);
817 }
818
819 void
820 ctl_set_lun_transit(struct ctl_scsiio *ctsio)
821 {
822         /* "Logical unit not ready, asymmetric access state transition" */
823         ctl_set_sense(ctsio,
824                       /*current_error*/ 1,
825                       /*sense_key*/ SSD_KEY_NOT_READY,
826                       /*asc*/ 0x04,
827                       /*ascq*/ 0x0a,
828                       SSD_ELEM_NONE);
829 }
830
831 void
832 ctl_set_lun_standby(struct ctl_scsiio *ctsio)
833 {
834         /* "Logical unit not ready, target port in standby state" */
835         ctl_set_sense(ctsio,
836                       /*current_error*/ 1,
837                       /*sense_key*/ SSD_KEY_NOT_READY,
838                       /*asc*/ 0x04,
839                       /*ascq*/ 0x0b,
840                       SSD_ELEM_NONE);
841 }
842
843 void
844 ctl_set_lun_unavail(struct ctl_scsiio *ctsio)
845 {
846         /* "Logical unit not ready, target port in unavailable state" */
847         ctl_set_sense(ctsio,
848                       /*current_error*/ 1,
849                       /*sense_key*/ SSD_KEY_NOT_READY,
850                       /*asc*/ 0x04,
851                       /*ascq*/ 0x0c,
852                       SSD_ELEM_NONE);
853 }
854
855 void
856 ctl_set_medium_format_corrupted(struct ctl_scsiio *ctsio)
857 {
858         /* "Medium format corrupted" */
859         ctl_set_sense(ctsio,
860                       /*current_error*/ 1,
861                       /*sense_key*/ SSD_KEY_MEDIUM_ERROR,
862                       /*asc*/ 0x31,
863                       /*ascq*/ 0x00,
864                       SSD_ELEM_NONE);
865 }
866
867 void
868 ctl_set_medium_magazine_inaccessible(struct ctl_scsiio *ctsio)
869 {
870         /* "Medium magazine not accessible" */
871         ctl_set_sense(ctsio,
872                       /*current_error*/ 1,
873                       /*sense_key*/ SSD_KEY_NOT_READY,
874                       /*asc*/ 0x3b,
875                       /*ascq*/ 0x11,
876                       SSD_ELEM_NONE);
877 }
878
879 void
880 ctl_set_data_phase_error(struct ctl_scsiio *ctsio)
881 {
882         /* "Data phase error" */
883         ctl_set_sense(ctsio,
884                       /*current_error*/ 1,
885                       /*sense_key*/ SSD_KEY_NOT_READY,
886                       /*asc*/ 0x4b,
887                       /*ascq*/ 0x00,
888                       SSD_ELEM_NONE);
889 }
890
891 void
892 ctl_set_reservation_conflict(struct ctl_scsiio *ctsio)
893 {
894         struct scsi_sense_data *sense;
895
896         sense = &ctsio->sense_data;
897         memset(sense, 0, sizeof(*sense));
898         ctsio->scsi_status = SCSI_STATUS_RESERV_CONFLICT;
899         ctsio->sense_len = 0;
900         ctsio->io_hdr.status = CTL_SCSI_ERROR;
901 }
902
903 void
904 ctl_set_queue_full(struct ctl_scsiio *ctsio)
905 {
906         struct scsi_sense_data *sense;
907
908         sense = &ctsio->sense_data;
909         memset(sense, 0, sizeof(*sense));
910         ctsio->scsi_status = SCSI_STATUS_QUEUE_FULL;
911         ctsio->sense_len = 0;
912         ctsio->io_hdr.status = CTL_SCSI_ERROR;
913 }
914
915 void
916 ctl_set_busy(struct ctl_scsiio *ctsio)
917 {
918         struct scsi_sense_data *sense;
919
920         sense = &ctsio->sense_data;
921         memset(sense, 0, sizeof(*sense));
922         ctsio->scsi_status = SCSI_STATUS_BUSY;
923         ctsio->sense_len = 0;
924         ctsio->io_hdr.status = CTL_SCSI_ERROR;
925 }
926
927 void
928 ctl_set_task_aborted(struct ctl_scsiio *ctsio)
929 {
930         struct scsi_sense_data *sense;
931
932         sense = &ctsio->sense_data;
933         memset(sense, 0, sizeof(*sense));
934         ctsio->scsi_status = SCSI_STATUS_TASK_ABORTED;
935         ctsio->sense_len = 0;
936         ctsio->io_hdr.status = CTL_CMD_ABORTED;
937 }
938
939 void
940 ctl_set_hw_write_protected(struct ctl_scsiio *ctsio)
941 {
942         /* "Hardware write protected" */
943         ctl_set_sense(ctsio,
944                       /*current_error*/ 1,
945                       /*sense_key*/ SSD_KEY_DATA_PROTECT,
946                       /*asc*/ 0x27,
947                       /*ascq*/ 0x01,
948                       SSD_ELEM_NONE);
949 }
950
951 void
952 ctl_set_space_alloc_fail(struct ctl_scsiio *ctsio)
953 {
954         /* "Space allocation failed write protect" */
955         ctl_set_sense(ctsio,
956                       /*current_error*/ 1,
957                       /*sense_key*/ SSD_KEY_DATA_PROTECT,
958                       /*asc*/ 0x27,
959                       /*ascq*/ 0x07,
960                       SSD_ELEM_NONE);
961 }
962
963 void
964 ctl_set_success(struct ctl_scsiio *ctsio)
965 {
966         struct scsi_sense_data *sense;
967
968         sense = &ctsio->sense_data;
969         memset(sense, 0, sizeof(*sense));
970         ctsio->scsi_status = SCSI_STATUS_OK;
971         ctsio->sense_len = 0;
972         ctsio->io_hdr.status = CTL_SUCCESS;
973 }