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