xref: /freebsd/sys/cam/ctl/ctl_error.c (revision 0957b409)
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 }
990