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