Deleted Added
full compact
scsi_all.c (223081) scsi_all.c (225950)
1/*-
2 * Implementation of Utility functions for all SCSI device types.
3 *
4 * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998, 2003 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Implementation of Utility functions for all SCSI device types.
3 *
4 * Copyright (c) 1997, 1998, 1999 Justin T. Gibbs.
5 * Copyright (c) 1997, 1998, 2003 Kenneth D. Merry.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 14 unchanged lines hidden (view full) ---

23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_all.c 223081 2011-06-14 14:53:17Z gibbs $");
31__FBSDID("$FreeBSD: head/sys/cam/scsi/scsi_all.c 225950 2011-10-03 20:32:55Z ken $");
32
33#include <sys/param.h>
32
33#include <sys/param.h>
34#include <sys/types.h>
35#include <sys/stdint.h>
34
35#ifdef _KERNEL
36#include <opt_scsi.h>
37
38#include <sys/systm.h>
39#include <sys/libkern.h>
40#include <sys/kernel.h>
41#include <sys/sysctl.h>

--- 7 unchanged lines hidden (view full) ---

49#include <cam/cam.h>
50#include <cam/cam_ccb.h>
51#include <cam/cam_queue.h>
52#include <cam/cam_xpt.h>
53#include <cam/scsi/scsi_all.h>
54#include <sys/sbuf.h>
55#ifndef _KERNEL
56#include <camlib.h>
36
37#ifdef _KERNEL
38#include <opt_scsi.h>
39
40#include <sys/systm.h>
41#include <sys/libkern.h>
42#include <sys/kernel.h>
43#include <sys/sysctl.h>

--- 7 unchanged lines hidden (view full) ---

51#include <cam/cam.h>
52#include <cam/cam_ccb.h>
53#include <cam/cam_queue.h>
54#include <cam/cam_xpt.h>
55#include <cam/scsi/scsi_all.h>
56#include <sys/sbuf.h>
57#ifndef _KERNEL
58#include <camlib.h>
59#include <stddef.h>
57
58#ifndef FALSE
59#define FALSE 0
60#endif /* FALSE */
61#ifndef TRUE
62#define TRUE 1
63#endif /* TRUE */
64#define ERESTART -1 /* restart syscall */

--- 538 unchanged lines hidden (view full) ---

603 caddr_t match;
604 int i, j;
605 u_int32_t opmask;
606 u_int16_t pd_type;
607 int num_ops[2];
608 struct op_table_entry *table[2];
609 int num_tables;
610
60
61#ifndef FALSE
62#define FALSE 0
63#endif /* FALSE */
64#ifndef TRUE
65#define TRUE 1
66#endif /* TRUE */
67#define ERESTART -1 /* restart syscall */

--- 538 unchanged lines hidden (view full) ---

606 caddr_t match;
607 int i, j;
608 u_int32_t opmask;
609 u_int16_t pd_type;
610 int num_ops[2];
611 struct op_table_entry *table[2];
612 int num_tables;
613
611 pd_type = SID_TYPE(inq_data);
614 /*
615 * If we've got inquiry data, use it to determine what type of
616 * device we're dealing with here. Otherwise, assume direct
617 * access.
618 */
619 if (inq_data == NULL) {
620 pd_type = T_DIRECT;
621 match = NULL;
622 } else {
623 pd_type = SID_TYPE(inq_data);
612
624
613 match = cam_quirkmatch((caddr_t)inq_data,
614 (caddr_t)scsi_op_quirk_table,
615 sizeof(scsi_op_quirk_table)/
616 sizeof(*scsi_op_quirk_table),
617 sizeof(*scsi_op_quirk_table),
618 scsi_inquiry_match);
625 match = cam_quirkmatch((caddr_t)inq_data,
626 (caddr_t)scsi_op_quirk_table,
627 sizeof(scsi_op_quirk_table)/
628 sizeof(*scsi_op_quirk_table),
629 sizeof(*scsi_op_quirk_table),
630 scsi_inquiry_match);
631 }
619
620 if (match != NULL) {
621 table[0] = ((struct scsi_op_quirk_entry *)match)->op_table;
622 num_ops[0] = ((struct scsi_op_quirk_entry *)match)->num_ops;
623 table[1] = scsi_op_codes;
624 num_ops[1] = sizeof(scsi_op_codes)/sizeof(scsi_op_codes[0]);
625 num_tables = 2;
626 } else {

--- 67 unchanged lines hidden (view full) ---

694 { SSD_KEY_DATA_PROTECT, SS_FATAL|EACCES, "DATA PROTECT" },
695 { SSD_KEY_BLANK_CHECK, SS_FATAL|ENOSPC, "BLANK CHECK" },
696 { SSD_KEY_Vendor_Specific, SS_FATAL|EIO, "Vendor Specific" },
697 { SSD_KEY_COPY_ABORTED, SS_FATAL|EIO, "COPY ABORTED" },
698 { SSD_KEY_ABORTED_COMMAND, SS_RDEF, "ABORTED COMMAND" },
699 { SSD_KEY_EQUAL, SS_NOP, "EQUAL" },
700 { SSD_KEY_VOLUME_OVERFLOW, SS_FATAL|EIO, "VOLUME OVERFLOW" },
701 { SSD_KEY_MISCOMPARE, SS_NOP, "MISCOMPARE" },
632
633 if (match != NULL) {
634 table[0] = ((struct scsi_op_quirk_entry *)match)->op_table;
635 num_ops[0] = ((struct scsi_op_quirk_entry *)match)->num_ops;
636 table[1] = scsi_op_codes;
637 num_ops[1] = sizeof(scsi_op_codes)/sizeof(scsi_op_codes[0]);
638 num_tables = 2;
639 } else {

--- 67 unchanged lines hidden (view full) ---

707 { SSD_KEY_DATA_PROTECT, SS_FATAL|EACCES, "DATA PROTECT" },
708 { SSD_KEY_BLANK_CHECK, SS_FATAL|ENOSPC, "BLANK CHECK" },
709 { SSD_KEY_Vendor_Specific, SS_FATAL|EIO, "Vendor Specific" },
710 { SSD_KEY_COPY_ABORTED, SS_FATAL|EIO, "COPY ABORTED" },
711 { SSD_KEY_ABORTED_COMMAND, SS_RDEF, "ABORTED COMMAND" },
712 { SSD_KEY_EQUAL, SS_NOP, "EQUAL" },
713 { SSD_KEY_VOLUME_OVERFLOW, SS_FATAL|EIO, "VOLUME OVERFLOW" },
714 { SSD_KEY_MISCOMPARE, SS_NOP, "MISCOMPARE" },
702 { SSD_KEY_RESERVED, SS_FATAL|EIO, "RESERVED" }
715 { SSD_KEY_COMPLETED, SS_NOP, "COMPLETED" }
703};
704
705const int sense_key_table_size =
706 sizeof(sense_key_table)/sizeof(sense_key_table[0]);
707
708static struct asc_table_entry quantum_fireball_entries[] = {
709 { SST(0x04, 0x0b, SS_START | SSQ_DECREMENT_COUNT | ENXIO,
710 "Logical unit not ready, initializing cmd. required") }

--- 346 unchanged lines hidden (view full) ---

1057 "Logical block guard check failed") },
1058 /* DT W O */
1059 { SST(0x10, 0x02, SS_RDEF, /* XXX TBD */
1060 "Logical block application tag check failed") },
1061 /* DT W O */
1062 { SST(0x10, 0x03, SS_RDEF, /* XXX TBD */
1063 "Logical block reference tag check failed") },
1064 /* DT WRO BK */
716};
717
718const int sense_key_table_size =
719 sizeof(sense_key_table)/sizeof(sense_key_table[0]);
720
721static struct asc_table_entry quantum_fireball_entries[] = {
722 { SST(0x04, 0x0b, SS_START | SSQ_DECREMENT_COUNT | ENXIO,
723 "Logical unit not ready, initializing cmd. required") }

--- 346 unchanged lines hidden (view full) ---

1070 "Logical block guard check failed") },
1071 /* DT W O */
1072 { SST(0x10, 0x02, SS_RDEF, /* XXX TBD */
1073 "Logical block application tag check failed") },
1074 /* DT W O */
1075 { SST(0x10, 0x03, SS_RDEF, /* XXX TBD */
1076 "Logical block reference tag check failed") },
1077 /* DT WRO BK */
1065 { SST(0x11, 0x00, SS_RDEF,
1078 { SST(0x11, 0x00, SS_FATAL|EIO,
1066 "Unrecovered read error") },
1067 /* DT WRO BK */
1079 "Unrecovered read error") },
1080 /* DT WRO BK */
1068 { SST(0x11, 0x01, SS_RDEF,
1081 { SST(0x11, 0x01, SS_FATAL|EIO,
1069 "Read retries exhausted") },
1070 /* DT WRO BK */
1082 "Read retries exhausted") },
1083 /* DT WRO BK */
1071 { SST(0x11, 0x02, SS_RDEF,
1084 { SST(0x11, 0x02, SS_FATAL|EIO,
1072 "Error too long to correct") },
1073 /* DT W O BK */
1085 "Error too long to correct") },
1086 /* DT W O BK */
1074 { SST(0x11, 0x03, SS_RDEF,
1087 { SST(0x11, 0x03, SS_FATAL|EIO,
1075 "Multiple read errors") },
1076 /* D W O BK */
1088 "Multiple read errors") },
1089 /* D W O BK */
1077 { SST(0x11, 0x04, SS_RDEF,
1090 { SST(0x11, 0x04, SS_FATAL|EIO,
1078 "Unrecovered read error - auto reallocate failed") },
1079 /* WRO B */
1091 "Unrecovered read error - auto reallocate failed") },
1092 /* WRO B */
1080 { SST(0x11, 0x05, SS_RDEF,
1093 { SST(0x11, 0x05, SS_FATAL|EIO,
1081 "L-EC uncorrectable error") },
1082 /* WRO B */
1094 "L-EC uncorrectable error") },
1095 /* WRO B */
1083 { SST(0x11, 0x06, SS_RDEF,
1096 { SST(0x11, 0x06, SS_FATAL|EIO,
1084 "CIRC unrecovered error") },
1085 /* W O B */
1086 { SST(0x11, 0x07, SS_RDEF,
1087 "Data re-synchronization error") },
1088 /* T */
1089 { SST(0x11, 0x08, SS_RDEF,
1090 "Incomplete block read") },
1091 /* T */
1092 { SST(0x11, 0x09, SS_RDEF,
1093 "No gap found") },
1094 /* DT O BK */
1095 { SST(0x11, 0x0A, SS_RDEF,
1096 "Miscorrected error") },
1097 /* D W O BK */
1097 "CIRC unrecovered error") },
1098 /* W O B */
1099 { SST(0x11, 0x07, SS_RDEF,
1100 "Data re-synchronization error") },
1101 /* T */
1102 { SST(0x11, 0x08, SS_RDEF,
1103 "Incomplete block read") },
1104 /* T */
1105 { SST(0x11, 0x09, SS_RDEF,
1106 "No gap found") },
1107 /* DT O BK */
1108 { SST(0x11, 0x0A, SS_RDEF,
1109 "Miscorrected error") },
1110 /* D W O BK */
1098 { SST(0x11, 0x0B, SS_RDEF,
1111 { SST(0x11, 0x0B, SS_FATAL|EIO,
1099 "Unrecovered read error - recommend reassignment") },
1100 /* D W O BK */
1112 "Unrecovered read error - recommend reassignment") },
1113 /* D W O BK */
1101 { SST(0x11, 0x0C, SS_RDEF,
1114 { SST(0x11, 0x0C, SS_FATAL|EIO,
1102 "Unrecovered read error - recommend rewrite the data") },
1103 /* DT WRO B */
1104 { SST(0x11, 0x0D, SS_RDEF,
1105 "De-compression CRC error") },
1106 /* DT WRO B */
1107 { SST(0x11, 0x0E, SS_RDEF,
1108 "Cannot decompress using declared algorithm") },
1109 /* R */

--- 1675 unchanged lines hidden (view full) ---

2785 const struct asc_table_entry *asc_entry;
2786 const struct sense_key_table_entry *sense_entry;
2787
2788 fetchtableentries(sense_key, asc, ascq,
2789 inq_data,
2790 &sense_entry,
2791 &asc_entry);
2792
1115 "Unrecovered read error - recommend rewrite the data") },
1116 /* DT WRO B */
1117 { SST(0x11, 0x0D, SS_RDEF,
1118 "De-compression CRC error") },
1119 /* DT WRO B */
1120 { SST(0x11, 0x0E, SS_RDEF,
1121 "Cannot decompress using declared algorithm") },
1122 /* R */

--- 1675 unchanged lines hidden (view full) ---

2798 const struct asc_table_entry *asc_entry;
2799 const struct sense_key_table_entry *sense_entry;
2800
2801 fetchtableentries(sense_key, asc, ascq,
2802 inq_data,
2803 &sense_entry,
2804 &asc_entry);
2805
2793 *sense_key_desc = sense_entry->desc;
2806 if (sense_entry != NULL)
2807 *sense_key_desc = sense_entry->desc;
2808 else
2809 *sense_key_desc = "Invalid Sense Key";
2794
2795 if (asc_entry != NULL)
2796 *asc_desc = asc_entry->desc;
2797 else if (asc >= 0x80 && asc <= 0xff)
2798 *asc_desc = "Vendor Specific ASC";
2799 else if (ascq >= 0x80 && ascq <= 0xff)
2800 *asc_desc = "Vendor Specific ASCQ";
2801 else

--- 9 unchanged lines hidden (view full) ---

2811scsi_error_action(struct ccb_scsiio *csio, struct scsi_inquiry_data *inq_data,
2812 u_int32_t sense_flags)
2813{
2814 const struct asc_table_entry *asc_entry;
2815 const struct sense_key_table_entry *sense_entry;
2816 int error_code, sense_key, asc, ascq;
2817 scsi_sense_action action;
2818
2810
2811 if (asc_entry != NULL)
2812 *asc_desc = asc_entry->desc;
2813 else if (asc >= 0x80 && asc <= 0xff)
2814 *asc_desc = "Vendor Specific ASC";
2815 else if (ascq >= 0x80 && ascq <= 0xff)
2816 *asc_desc = "Vendor Specific ASCQ";
2817 else

--- 9 unchanged lines hidden (view full) ---

2827scsi_error_action(struct ccb_scsiio *csio, struct scsi_inquiry_data *inq_data,
2828 u_int32_t sense_flags)
2829{
2830 const struct asc_table_entry *asc_entry;
2831 const struct sense_key_table_entry *sense_entry;
2832 int error_code, sense_key, asc, ascq;
2833 scsi_sense_action action;
2834
2819 scsi_extract_sense(&csio->sense_data, &error_code,
2820 &sense_key, &asc, &ascq);
2835 scsi_extract_sense_len(&csio->sense_data, csio->sense_len -
2836 csio->sense_resid, &error_code,
2837 &sense_key, &asc, &ascq, /*show_errors*/ 1);
2821
2838
2822 if (error_code == SSD_DEFERRED_ERROR) {
2839 if ((error_code == SSD_DEFERRED_ERROR)
2840 || (error_code == SSD_DESC_DEFERRED_ERROR)) {
2823 /*
2824 * XXX dufault@FreeBSD.org
2825 * This error doesn't relate to the command associated
2826 * with this request sense. A deferred error is an error
2827 * for a command that has already returned GOOD status
2828 * (see SCSI2 8.2.14.2).
2829 *
2830 * By my reading of that section, it looks like the current

--- 21 unchanged lines hidden (view full) ---

2852
2853 /*
2854 * Override the 'No additional Sense' entry (0,0)
2855 * with the error action of the sense key.
2856 */
2857 if (asc_entry != NULL
2858 && (asc != 0 || ascq != 0))
2859 action = asc_entry->action;
2841 /*
2842 * XXX dufault@FreeBSD.org
2843 * This error doesn't relate to the command associated
2844 * with this request sense. A deferred error is an error
2845 * for a command that has already returned GOOD status
2846 * (see SCSI2 8.2.14.2).
2847 *
2848 * By my reading of that section, it looks like the current

--- 21 unchanged lines hidden (view full) ---

2870
2871 /*
2872 * Override the 'No additional Sense' entry (0,0)
2873 * with the error action of the sense key.
2874 */
2875 if (asc_entry != NULL
2876 && (asc != 0 || ascq != 0))
2877 action = asc_entry->action;
2860 else
2878 else if (sense_entry != NULL)
2861 action = sense_entry->action;
2879 action = sense_entry->action;
2880 else
2881 action = SS_RETRY|SSQ_DECREMENT_COUNT|SSQ_PRINT_SENSE;
2862
2863 if (sense_key == SSD_KEY_RECOVERED_ERROR) {
2864 /*
2865 * The action succeeded but the device wants
2866 * the user to know that some recovery action
2867 * was required.
2868 */
2869 action &= ~(SS_MASK|SSQ_MASK|SS_ERRMASK);

--- 165 unchanged lines hidden (view full) ---

3035 scsi_op_desc(csio->cdb_io.cdb_bytes[0], inq_data),
3036 scsi_cdb_string(csio->cdb_io.cdb_bytes, cdb_str,
3037 sizeof(cdb_str)));
3038 }
3039
3040 return(0);
3041}
3042
2882
2883 if (sense_key == SSD_KEY_RECOVERED_ERROR) {
2884 /*
2885 * The action succeeded but the device wants
2886 * the user to know that some recovery action
2887 * was required.
2888 */
2889 action &= ~(SS_MASK|SSQ_MASK|SS_ERRMASK);

--- 165 unchanged lines hidden (view full) ---

3055 scsi_op_desc(csio->cdb_io.cdb_bytes[0], inq_data),
3056 scsi_cdb_string(csio->cdb_io.cdb_bytes, cdb_str,
3057 sizeof(cdb_str)));
3058 }
3059
3060 return(0);
3061}
3062
3063/*
3064 * Iterate over sense descriptors. Each descriptor is passed into iter_func().
3065 * If iter_func() returns 0, list traversal continues. If iter_func()
3066 * returns non-zero, list traversal is stopped.
3067 */
3068void
3069scsi_desc_iterate(struct scsi_sense_data_desc *sense, u_int sense_len,
3070 int (*iter_func)(struct scsi_sense_data_desc *sense,
3071 u_int, struct scsi_sense_desc_header *,
3072 void *), void *arg)
3073{
3074 int cur_pos;
3075 int desc_len;
3043
3076
3077 /*
3078 * First make sure the extra length field is present.
3079 */
3080 if (SSD_DESC_IS_PRESENT(sense, sense_len, extra_len) == 0)
3081 return;
3082
3083 /*
3084 * The length of data actually returned may be different than the
3085 * extra_len recorded in the sturcture.
3086 */
3087 desc_len = sense_len -offsetof(struct scsi_sense_data_desc, sense_desc);
3088
3089 /*
3090 * Limit this further by the extra length reported, and the maximum
3091 * allowed extra length.
3092 */
3093 desc_len = MIN(desc_len, MIN(sense->extra_len, SSD_EXTRA_MAX));
3094
3095 /*
3096 * Subtract the size of the header from the descriptor length.
3097 * This is to ensure that we have at least the header left, so we
3098 * don't have to check that inside the loop. This can wind up
3099 * being a negative value.
3100 */
3101 desc_len -= sizeof(struct scsi_sense_desc_header);
3102
3103 for (cur_pos = 0; cur_pos < desc_len;) {
3104 struct scsi_sense_desc_header *header;
3105
3106 header = (struct scsi_sense_desc_header *)
3107 &sense->sense_desc[cur_pos];
3108
3109 /*
3110 * Check to make sure we have the entire descriptor. We
3111 * don't call iter_func() unless we do.
3112 *
3113 * Note that although cur_pos is at the beginning of the
3114 * descriptor, desc_len already has the header length
3115 * subtracted. So the comparison of the length in the
3116 * header (which does not include the header itself) to
3117 * desc_len - cur_pos is correct.
3118 */
3119 if (header->length > (desc_len - cur_pos))
3120 break;
3121
3122 if (iter_func(sense, sense_len, header, arg) != 0)
3123 break;
3124
3125 cur_pos += sizeof(*header) + header->length;
3126 }
3127}
3128
3129struct scsi_find_desc_info {
3130 uint8_t desc_type;
3131 struct scsi_sense_desc_header *header;
3132};
3133
3134static int
3135scsi_find_desc_func(struct scsi_sense_data_desc *sense, u_int sense_len,
3136 struct scsi_sense_desc_header *header, void *arg)
3137{
3138 struct scsi_find_desc_info *desc_info;
3139
3140 desc_info = (struct scsi_find_desc_info *)arg;
3141
3142 if (header->desc_type == desc_info->desc_type) {
3143 desc_info->header = header;
3144
3145 /* We found the descriptor, tell the iterator to stop. */
3146 return (1);
3147 } else
3148 return (0);
3149}
3150
3044/*
3151/*
3152 * Given a descriptor type, return a pointer to it if it is in the sense
3153 * data and not truncated. Avoiding truncating sense data will simplify
3154 * things significantly for the caller.
3155 */
3156uint8_t *
3157scsi_find_desc(struct scsi_sense_data_desc *sense, u_int sense_len,
3158 uint8_t desc_type)
3159{
3160 struct scsi_find_desc_info desc_info;
3161
3162 desc_info.desc_type = desc_type;
3163 desc_info.header = NULL;
3164
3165 scsi_desc_iterate(sense, sense_len, scsi_find_desc_func, &desc_info);
3166
3167 return ((uint8_t *)desc_info.header);
3168}
3169
3170/*
3171 * Fill in SCSI sense data with the specified parameters. This routine can
3172 * fill in either fixed or descriptor type sense data.
3173 */
3174void
3175scsi_set_sense_data_va(struct scsi_sense_data *sense_data,
3176 scsi_sense_data_type sense_format, int current_error,
3177 int sense_key, int asc, int ascq, va_list ap)
3178{
3179 int descriptor_sense;
3180 scsi_sense_elem_type elem_type;
3181
3182 /*
3183 * Determine whether to return fixed or descriptor format sense
3184 * data. If the user specifies SSD_TYPE_NONE for some reason,
3185 * they'll just get fixed sense data.
3186 */
3187 if (sense_format == SSD_TYPE_DESC)
3188 descriptor_sense = 1;
3189 else
3190 descriptor_sense = 0;
3191
3192 /*
3193 * Zero the sense data, so that we don't pass back any garbage data
3194 * to the user.
3195 */
3196 memset(sense_data, 0, sizeof(*sense_data));
3197
3198 if (descriptor_sense != 0) {
3199 struct scsi_sense_data_desc *sense;
3200
3201 sense = (struct scsi_sense_data_desc *)sense_data;
3202 /*
3203 * The descriptor sense format eliminates the use of the
3204 * valid bit.
3205 */
3206 if (current_error != 0)
3207 sense->error_code = SSD_DESC_CURRENT_ERROR;
3208 else
3209 sense->error_code = SSD_DESC_DEFERRED_ERROR;
3210 sense->sense_key = sense_key;
3211 sense->add_sense_code = asc;
3212 sense->add_sense_code_qual = ascq;
3213 /*
3214 * Start off with no extra length, since the above data
3215 * fits in the standard descriptor sense information.
3216 */
3217 sense->extra_len = 0;
3218 while ((elem_type = (scsi_sense_elem_type)va_arg(ap,
3219 scsi_sense_elem_type)) != SSD_ELEM_NONE) {
3220 int sense_len, len_to_copy;
3221 uint8_t *data;
3222
3223 if (elem_type >= SSD_ELEM_MAX) {
3224 printf("%s: invalid sense type %d\n", __func__,
3225 elem_type);
3226 break;
3227 }
3228
3229 sense_len = (int)va_arg(ap, int);
3230 len_to_copy = MIN(sense_len, SSD_EXTRA_MAX -
3231 sense->extra_len);
3232 data = (uint8_t *)va_arg(ap, uint8_t *);
3233
3234 /*
3235 * We've already consumed the arguments for this one.
3236 */
3237 if (elem_type == SSD_ELEM_SKIP)
3238 continue;
3239
3240 switch (elem_type) {
3241 case SSD_ELEM_DESC: {
3242
3243 /*
3244 * This is a straight descriptor. All we
3245 * need to do is copy the data in.
3246 */
3247 bcopy(data, &sense->sense_desc[
3248 sense->extra_len], len_to_copy);
3249 sense->extra_len += len_to_copy;
3250 break;
3251 }
3252 case SSD_ELEM_SKS: {
3253 struct scsi_sense_sks sks;
3254
3255 bzero(&sks, sizeof(sks));
3256
3257 /*
3258 * This is already-formatted sense key
3259 * specific data. We just need to fill out
3260 * the header and copy everything in.
3261 */
3262 bcopy(data, &sks.sense_key_spec,
3263 MIN(len_to_copy,
3264 sizeof(sks.sense_key_spec)));
3265
3266 sks.desc_type = SSD_DESC_SKS;
3267 sks.length = sizeof(sks) -
3268 offsetof(struct scsi_sense_sks, reserved1);
3269 bcopy(&sks,&sense->sense_desc[sense->extra_len],
3270 sizeof(sks));
3271 sense->extra_len += sizeof(sks);
3272 break;
3273 }
3274 case SSD_ELEM_INFO:
3275 case SSD_ELEM_COMMAND: {
3276 struct scsi_sense_command cmd;
3277 struct scsi_sense_info info;
3278 uint8_t *data_dest;
3279 uint8_t *descriptor;
3280 int descriptor_size, i, copy_len;
3281
3282 bzero(&cmd, sizeof(cmd));
3283 bzero(&info, sizeof(info));
3284
3285 /*
3286 * Command or information data. The
3287 * operate in pretty much the same way.
3288 */
3289 if (elem_type == SSD_ELEM_COMMAND) {
3290 len_to_copy = MIN(len_to_copy,
3291 sizeof(cmd.command_info));
3292 descriptor = (uint8_t *)&cmd;
3293 descriptor_size = sizeof(cmd);
3294 data_dest =(uint8_t *)&cmd.command_info;
3295 cmd.desc_type = SSD_DESC_COMMAND;
3296 cmd.length = sizeof(cmd) -
3297 offsetof(struct scsi_sense_command,
3298 reserved);
3299 } else {
3300 len_to_copy = MIN(len_to_copy,
3301 sizeof(info.info));
3302 descriptor = (uint8_t *)&info;
3303 descriptor_size = sizeof(cmd);
3304 data_dest = (uint8_t *)&info.info;
3305 info.desc_type = SSD_DESC_INFO;
3306 info.byte2 = SSD_INFO_VALID;
3307 info.length = sizeof(info) -
3308 offsetof(struct scsi_sense_info,
3309 byte2);
3310 }
3311
3312 /*
3313 * Copy this in reverse because the spec
3314 * (SPC-4) says that when 4 byte quantities
3315 * are stored in this 8 byte field, the
3316 * first four bytes shall be 0.
3317 *
3318 * So we fill the bytes in from the end, and
3319 * if we have less than 8 bytes to copy,
3320 * the initial, most significant bytes will
3321 * be 0.
3322 */
3323 for (i = sense_len - 1; i >= 0 &&
3324 len_to_copy > 0; i--, len_to_copy--)
3325 data_dest[len_to_copy - 1] = data[i];
3326
3327 /*
3328 * This calculation looks much like the
3329 * initial len_to_copy calculation, but
3330 * we have to do it again here, because
3331 * we're looking at a larger amount that
3332 * may or may not fit. It's not only the
3333 * data the user passed in, but also the
3334 * rest of the descriptor.
3335 */
3336 copy_len = MIN(descriptor_size,
3337 SSD_EXTRA_MAX - sense->extra_len);
3338 bcopy(descriptor, &sense->sense_desc[
3339 sense->extra_len], copy_len);
3340 sense->extra_len += copy_len;
3341 break;
3342 }
3343 case SSD_ELEM_FRU: {
3344 struct scsi_sense_fru fru;
3345 int copy_len;
3346
3347 bzero(&fru, sizeof(fru));
3348
3349 fru.desc_type = SSD_DESC_FRU;
3350 fru.length = sizeof(fru) -
3351 offsetof(struct scsi_sense_fru, reserved);
3352 fru.fru = *data;
3353
3354 copy_len = MIN(sizeof(fru), SSD_EXTRA_MAX -
3355 sense->extra_len);
3356 bcopy(&fru, &sense->sense_desc[
3357 sense->extra_len], copy_len);
3358 sense->extra_len += copy_len;
3359 break;
3360 }
3361 case SSD_ELEM_STREAM: {
3362 struct scsi_sense_stream stream_sense;
3363 int copy_len;
3364
3365 bzero(&stream_sense, sizeof(stream_sense));
3366 stream_sense.desc_type = SSD_DESC_STREAM;
3367 stream_sense.length = sizeof(stream_sense) -
3368 offsetof(struct scsi_sense_stream, reserved);
3369 stream_sense.byte3 = *data;
3370
3371 copy_len = MIN(sizeof(stream_sense),
3372 SSD_EXTRA_MAX - sense->extra_len);
3373 bcopy(&stream_sense, &sense->sense_desc[
3374 sense->extra_len], copy_len);
3375 sense->extra_len += copy_len;
3376 break;
3377 }
3378 default:
3379 /*
3380 * We shouldn't get here, but if we do, do
3381 * nothing. We've already consumed the
3382 * arguments above.
3383 */
3384 break;
3385 }
3386 }
3387 } else {
3388 struct scsi_sense_data_fixed *sense;
3389
3390 sense = (struct scsi_sense_data_fixed *)sense_data;
3391
3392 if (current_error != 0)
3393 sense->error_code = SSD_CURRENT_ERROR;
3394 else
3395 sense->error_code = SSD_DEFERRED_ERROR;
3396
3397 sense->flags = sense_key;
3398 sense->add_sense_code = asc;
3399 sense->add_sense_code_qual = ascq;
3400 /*
3401 * We've set the ASC and ASCQ, so we have 6 more bytes of
3402 * valid data. If we wind up setting any of the other
3403 * fields, we'll bump this to 10 extra bytes.
3404 */
3405 sense->extra_len = 6;
3406
3407 while ((elem_type = (scsi_sense_elem_type)va_arg(ap,
3408 scsi_sense_elem_type)) != SSD_ELEM_NONE) {
3409 int sense_len, len_to_copy;
3410 uint8_t *data;
3411
3412 if (elem_type >= SSD_ELEM_MAX) {
3413 printf("%s: invalid sense type %d\n", __func__,
3414 elem_type);
3415 break;
3416 }
3417 /*
3418 * If we get in here, just bump the extra length to
3419 * 10 bytes. That will encompass anything we're
3420 * going to set here.
3421 */
3422 sense->extra_len = 10;
3423 sense_len = (int)va_arg(ap, int);
3424 len_to_copy = MIN(sense_len, SSD_EXTRA_MAX -
3425 sense->extra_len);
3426 data = (uint8_t *)va_arg(ap, uint8_t *);
3427
3428 switch (elem_type) {
3429 case SSD_ELEM_SKS:
3430 /*
3431 * The user passed in pre-formatted sense
3432 * key specific data.
3433 */
3434 bcopy(data, &sense->sense_key_spec[0],
3435 MIN(sizeof(sense->sense_key_spec),
3436 sense_len));
3437 break;
3438 case SSD_ELEM_INFO:
3439 case SSD_ELEM_COMMAND: {
3440 uint8_t *data_dest;
3441 int i;
3442
3443 if (elem_type == SSD_ELEM_COMMAND)
3444 data_dest = &sense->cmd_spec_info[0];
3445 else {
3446 data_dest = &sense->info[0];
3447 /*
3448 * We're setting the info field, so
3449 * set the valid bit.
3450 */
3451 sense->error_code |= SSD_ERRCODE_VALID;
3452 }
3453
3454 /*
3455 * Copy this in reverse so that if we have
3456 * less than 4 bytes to fill, the least
3457 * significant bytes will be at the end.
3458 * If we have more than 4 bytes, only the
3459 * least significant bytes will be included.
3460 */
3461 for (i = sense_len - 1; i >= 0 &&
3462 len_to_copy > 0; i--, len_to_copy--)
3463 data_dest[len_to_copy - 1] = data[i];
3464
3465 break;
3466 }
3467 case SSD_ELEM_FRU:
3468 sense->fru = *data;
3469 break;
3470 case SSD_ELEM_STREAM:
3471 sense->flags |= *data;
3472 break;
3473 case SSD_ELEM_DESC:
3474 default:
3475
3476 /*
3477 * If the user passes in descriptor sense,
3478 * we can't handle that in fixed format.
3479 * So just skip it, and any unknown argument
3480 * types.
3481 */
3482 break;
3483 }
3484 }
3485 }
3486}
3487
3488void
3489scsi_set_sense_data(struct scsi_sense_data *sense_data,
3490 scsi_sense_data_type sense_format, int current_error,
3491 int sense_key, int asc, int ascq, ...)
3492{
3493 va_list ap;
3494
3495 va_start(ap, ascq);
3496 scsi_set_sense_data_va(sense_data, sense_format, current_error,
3497 sense_key, asc, ascq, ap);
3498 va_end(ap);
3499}
3500
3501/*
3502 * Get sense information for three similar sense data types.
3503 */
3504int
3505scsi_get_sense_info(struct scsi_sense_data *sense_data, u_int sense_len,
3506 uint8_t info_type, uint64_t *info, int64_t *signed_info)
3507{
3508 scsi_sense_data_type sense_type;
3509
3510 if (sense_len == 0)
3511 goto bailout;
3512
3513 sense_type = scsi_sense_type(sense_data);
3514
3515 switch (sense_type) {
3516 case SSD_TYPE_DESC: {
3517 struct scsi_sense_data_desc *sense;
3518 uint8_t *desc;
3519
3520 sense = (struct scsi_sense_data_desc *)sense_data;
3521
3522 desc = scsi_find_desc(sense, sense_len, info_type);
3523 if (desc == NULL)
3524 goto bailout;
3525
3526 switch (info_type) {
3527 case SSD_DESC_INFO: {
3528 struct scsi_sense_info *info_desc;
3529
3530 info_desc = (struct scsi_sense_info *)desc;
3531 *info = scsi_8btou64(info_desc->info);
3532 if (signed_info != NULL)
3533 *signed_info = *info;
3534 break;
3535 }
3536 case SSD_DESC_COMMAND: {
3537 struct scsi_sense_command *cmd_desc;
3538
3539 cmd_desc = (struct scsi_sense_command *)desc;
3540
3541 *info = scsi_8btou64(cmd_desc->command_info);
3542 if (signed_info != NULL)
3543 *signed_info = *info;
3544 break;
3545 }
3546 case SSD_DESC_FRU: {
3547 struct scsi_sense_fru *fru_desc;
3548
3549 fru_desc = (struct scsi_sense_fru *)desc;
3550
3551 *info = fru_desc->fru;
3552 if (signed_info != NULL)
3553 *signed_info = (int8_t)fru_desc->fru;
3554 break;
3555 }
3556 default:
3557 goto bailout;
3558 break;
3559 }
3560 break;
3561 }
3562 case SSD_TYPE_FIXED: {
3563 struct scsi_sense_data_fixed *sense;
3564
3565 sense = (struct scsi_sense_data_fixed *)sense_data;
3566
3567 switch (info_type) {
3568 case SSD_DESC_INFO: {
3569 uint32_t info_val;
3570
3571 if ((sense->error_code & SSD_ERRCODE_VALID) == 0)
3572 goto bailout;
3573
3574 if (SSD_FIXED_IS_PRESENT(sense, sense_len, info) == 0)
3575 goto bailout;
3576
3577 info_val = scsi_4btoul(sense->info);
3578
3579 *info = info_val;
3580 if (signed_info != NULL)
3581 *signed_info = (int32_t)info_val;
3582 break;
3583 }
3584 case SSD_DESC_COMMAND: {
3585 uint32_t cmd_val;
3586
3587 if ((SSD_FIXED_IS_PRESENT(sense, sense_len,
3588 cmd_spec_info) == 0)
3589 || (SSD_FIXED_IS_FILLED(sense, cmd_spec_info) == 0))
3590 goto bailout;
3591
3592 cmd_val = scsi_4btoul(sense->cmd_spec_info);
3593 if (cmd_val == 0)
3594 goto bailout;
3595
3596 *info = cmd_val;
3597 if (signed_info != NULL)
3598 *signed_info = (int32_t)cmd_val;
3599 break;
3600 }
3601 case SSD_DESC_FRU:
3602 if ((SSD_FIXED_IS_PRESENT(sense, sense_len, fru) == 0)
3603 || (SSD_FIXED_IS_FILLED(sense, fru) == 0))
3604 goto bailout;
3605
3606 if (sense->fru == 0)
3607 goto bailout;
3608
3609 *info = sense->fru;
3610 if (signed_info != NULL)
3611 *signed_info = (int8_t)sense->fru;
3612 break;
3613 default:
3614 goto bailout;
3615 break;
3616 }
3617 break;
3618 }
3619 default:
3620 goto bailout;
3621 break;
3622 }
3623
3624 return (0);
3625bailout:
3626 return (1);
3627}
3628
3629int
3630scsi_get_sks(struct scsi_sense_data *sense_data, u_int sense_len, uint8_t *sks)
3631{
3632 scsi_sense_data_type sense_type;
3633
3634 if (sense_len == 0)
3635 goto bailout;
3636
3637 sense_type = scsi_sense_type(sense_data);
3638
3639 switch (sense_type) {
3640 case SSD_TYPE_DESC: {
3641 struct scsi_sense_data_desc *sense;
3642 struct scsi_sense_sks *desc;
3643
3644 sense = (struct scsi_sense_data_desc *)sense_data;
3645
3646 desc = (struct scsi_sense_sks *)scsi_find_desc(sense, sense_len,
3647 SSD_DESC_SKS);
3648 if (desc == NULL)
3649 goto bailout;
3650
3651 /*
3652 * No need to check the SKS valid bit for descriptor sense.
3653 * If the descriptor is present, it is valid.
3654 */
3655 bcopy(desc->sense_key_spec, sks, sizeof(desc->sense_key_spec));
3656 break;
3657 }
3658 case SSD_TYPE_FIXED: {
3659 struct scsi_sense_data_fixed *sense;
3660
3661 sense = (struct scsi_sense_data_fixed *)sense_data;
3662
3663 if ((SSD_FIXED_IS_PRESENT(sense, sense_len, sense_key_spec)== 0)
3664 || (SSD_FIXED_IS_FILLED(sense, sense_key_spec) == 0))
3665 goto bailout;
3666
3667 if ((sense->sense_key_spec[0] & SSD_SCS_VALID) == 0)
3668 goto bailout;
3669
3670 bcopy(sense->sense_key_spec, sks,sizeof(sense->sense_key_spec));
3671 break;
3672 }
3673 default:
3674 goto bailout;
3675 break;
3676 }
3677 return (0);
3678bailout:
3679 return (1);
3680}
3681
3682/*
3683 * Provide a common interface for fixed and descriptor sense to detect
3684 * whether we have block-specific sense information. It is clear by the
3685 * presence of the block descriptor in descriptor mode, but we have to
3686 * infer from the inquiry data and ILI bit in fixed mode.
3687 */
3688int
3689scsi_get_block_info(struct scsi_sense_data *sense_data, u_int sense_len,
3690 struct scsi_inquiry_data *inq_data, uint8_t *block_bits)
3691{
3692 scsi_sense_data_type sense_type;
3693
3694 if (inq_data != NULL) {
3695 switch (SID_TYPE(inq_data)) {
3696 case T_DIRECT:
3697 case T_RBC:
3698 break;
3699 default:
3700 goto bailout;
3701 break;
3702 }
3703 }
3704
3705 sense_type = scsi_sense_type(sense_data);
3706
3707 switch (sense_type) {
3708 case SSD_TYPE_DESC: {
3709 struct scsi_sense_data_desc *sense;
3710 struct scsi_sense_block *block;
3711
3712 sense = (struct scsi_sense_data_desc *)sense_data;
3713
3714 block = (struct scsi_sense_block *)scsi_find_desc(sense,
3715 sense_len, SSD_DESC_BLOCK);
3716 if (block == NULL)
3717 goto bailout;
3718
3719 *block_bits = block->byte3;
3720 break;
3721 }
3722 case SSD_TYPE_FIXED: {
3723 struct scsi_sense_data_fixed *sense;
3724
3725 sense = (struct scsi_sense_data_fixed *)sense_data;
3726
3727 if (SSD_FIXED_IS_PRESENT(sense, sense_len, flags) == 0)
3728 goto bailout;
3729
3730 if ((sense->flags & SSD_ILI) == 0)
3731 goto bailout;
3732
3733 *block_bits = sense->flags & SSD_ILI;
3734 break;
3735 }
3736 default:
3737 goto bailout;
3738 break;
3739 }
3740 return (0);
3741bailout:
3742 return (1);
3743}
3744
3745int
3746scsi_get_stream_info(struct scsi_sense_data *sense_data, u_int sense_len,
3747 struct scsi_inquiry_data *inq_data, uint8_t *stream_bits)
3748{
3749 scsi_sense_data_type sense_type;
3750
3751 if (inq_data != NULL) {
3752 switch (SID_TYPE(inq_data)) {
3753 case T_SEQUENTIAL:
3754 break;
3755 default:
3756 goto bailout;
3757 break;
3758 }
3759 }
3760
3761 sense_type = scsi_sense_type(sense_data);
3762
3763 switch (sense_type) {
3764 case SSD_TYPE_DESC: {
3765 struct scsi_sense_data_desc *sense;
3766 struct scsi_sense_stream *stream;
3767
3768 sense = (struct scsi_sense_data_desc *)sense_data;
3769
3770 stream = (struct scsi_sense_stream *)scsi_find_desc(sense,
3771 sense_len, SSD_DESC_STREAM);
3772 if (stream == NULL)
3773 goto bailout;
3774
3775 *stream_bits = stream->byte3;
3776 break;
3777 }
3778 case SSD_TYPE_FIXED: {
3779 struct scsi_sense_data_fixed *sense;
3780
3781 sense = (struct scsi_sense_data_fixed *)sense_data;
3782
3783 if (SSD_FIXED_IS_PRESENT(sense, sense_len, flags) == 0)
3784 goto bailout;
3785
3786 if ((sense->flags & (SSD_ILI|SSD_EOM|SSD_FILEMARK)) == 0)
3787 goto bailout;
3788
3789 *stream_bits = sense->flags & (SSD_ILI|SSD_EOM|SSD_FILEMARK);
3790 break;
3791 }
3792 default:
3793 goto bailout;
3794 break;
3795 }
3796 return (0);
3797bailout:
3798 return (1);
3799}
3800
3801void
3802scsi_info_sbuf(struct sbuf *sb, uint8_t *cdb, int cdb_len,
3803 struct scsi_inquiry_data *inq_data, uint64_t info)
3804{
3805 sbuf_printf(sb, "Info: %#jx", info);
3806}
3807
3808void
3809scsi_command_sbuf(struct sbuf *sb, uint8_t *cdb, int cdb_len,
3810 struct scsi_inquiry_data *inq_data, uint64_t csi)
3811{
3812 sbuf_printf(sb, "Command Specific Info: %#jx", csi);
3813}
3814
3815
3816void
3817scsi_progress_sbuf(struct sbuf *sb, uint16_t progress)
3818{
3819 sbuf_printf(sb, "Progress: %d%% (%d/%d) complete",
3820 (progress * 100) / SSD_SKS_PROGRESS_DENOM,
3821 progress, SSD_SKS_PROGRESS_DENOM);
3822}
3823
3824/*
3825 * Returns 1 for failure (i.e. SKS isn't valid) and 0 for success.
3826 */
3827int
3828scsi_sks_sbuf(struct sbuf *sb, int sense_key, uint8_t *sks)
3829{
3830 if ((sks[0] & SSD_SKS_VALID) == 0)
3831 return (1);
3832
3833 switch (sense_key) {
3834 case SSD_KEY_ILLEGAL_REQUEST: {
3835 struct scsi_sense_sks_field *field;
3836 int bad_command;
3837 char tmpstr[40];
3838
3839 /*Field Pointer*/
3840 field = (struct scsi_sense_sks_field *)sks;
3841
3842 if (field->byte0 & SSD_SKS_FIELD_CMD)
3843 bad_command = 1;
3844 else
3845 bad_command = 0;
3846
3847 tmpstr[0] = '\0';
3848
3849 /* Bit pointer is valid */
3850 if (field->byte0 & SSD_SKS_BPV)
3851 snprintf(tmpstr, sizeof(tmpstr), "bit %d ",
3852 field->byte0 & SSD_SKS_BIT_VALUE);
3853
3854 sbuf_printf(sb, "%s byte %d %sis invalid",
3855 bad_command ? "Command" : "Data",
3856 scsi_2btoul(field->field), tmpstr);
3857 break;
3858 }
3859 case SSD_KEY_UNIT_ATTENTION: {
3860 struct scsi_sense_sks_overflow *overflow;
3861
3862 overflow = (struct scsi_sense_sks_overflow *)sks;
3863
3864 /*UA Condition Queue Overflow*/
3865 sbuf_printf(sb, "Unit Attention Condition Queue %s",
3866 (overflow->byte0 & SSD_SKS_OVERFLOW_SET) ?
3867 "Overflowed" : "Did Not Overflow??");
3868 break;
3869 }
3870 case SSD_KEY_RECOVERED_ERROR:
3871 case SSD_KEY_HARDWARE_ERROR:
3872 case SSD_KEY_MEDIUM_ERROR: {
3873 struct scsi_sense_sks_retry *retry;
3874
3875 /*Actual Retry Count*/
3876 retry = (struct scsi_sense_sks_retry *)sks;
3877
3878 sbuf_printf(sb, "Actual Retry Count: %d",
3879 scsi_2btoul(retry->actual_retry_count));
3880 break;
3881 }
3882 case SSD_KEY_NO_SENSE:
3883 case SSD_KEY_NOT_READY: {
3884 struct scsi_sense_sks_progress *progress;
3885 int progress_val;
3886
3887 /*Progress Indication*/
3888 progress = (struct scsi_sense_sks_progress *)sks;
3889 progress_val = scsi_2btoul(progress->progress);
3890
3891 scsi_progress_sbuf(sb, progress_val);
3892 break;
3893 }
3894 case SSD_KEY_COPY_ABORTED: {
3895 struct scsi_sense_sks_segment *segment;
3896 char tmpstr[40];
3897
3898 /*Segment Pointer*/
3899 segment = (struct scsi_sense_sks_segment *)sks;
3900
3901 tmpstr[0] = '\0';
3902
3903 if (segment->byte0 & SSD_SKS_SEGMENT_BPV)
3904 snprintf(tmpstr, sizeof(tmpstr), "bit %d ",
3905 segment->byte0 & SSD_SKS_SEGMENT_BITPTR);
3906
3907 sbuf_printf(sb, "%s byte %d %sis invalid", (segment->byte0 &
3908 SSD_SKS_SEGMENT_SD) ? "Segment" : "Data",
3909 scsi_2btoul(segment->field), tmpstr);
3910 break;
3911 }
3912 default:
3913 sbuf_printf(sb, "Sense Key Specific: %#x,%#x", sks[0],
3914 scsi_2btoul(&sks[1]));
3915 break;
3916 }
3917
3918 return (0);
3919}
3920
3921void
3922scsi_fru_sbuf(struct sbuf *sb, uint64_t fru)
3923{
3924 sbuf_printf(sb, "Field Replaceable Unit: %d", (int)fru);
3925}
3926
3927void
3928scsi_stream_sbuf(struct sbuf *sb, uint8_t stream_bits, uint64_t info)
3929{
3930 int need_comma;
3931
3932 need_comma = 0;
3933 /*
3934 * XXX KDM this needs more descriptive decoding.
3935 */
3936 if (stream_bits & SSD_DESC_STREAM_FM) {
3937 sbuf_printf(sb, "Filemark");
3938 need_comma = 1;
3939 }
3940
3941 if (stream_bits & SSD_DESC_STREAM_EOM) {
3942 sbuf_printf(sb, "%sEOM", (need_comma) ? "," : "");
3943 need_comma = 1;
3944 }
3945
3946 if (stream_bits & SSD_DESC_STREAM_ILI)
3947 sbuf_printf(sb, "%sILI", (need_comma) ? "," : "");
3948
3949 sbuf_printf(sb, ": Info: %#jx", (uintmax_t) info);
3950}
3951
3952void
3953scsi_block_sbuf(struct sbuf *sb, uint8_t block_bits, uint64_t info)
3954{
3955 if (block_bits & SSD_DESC_BLOCK_ILI)
3956 sbuf_printf(sb, "ILI: residue %#jx", (uintmax_t) info);
3957}
3958
3959void
3960scsi_sense_info_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
3961 u_int sense_len, uint8_t *cdb, int cdb_len,
3962 struct scsi_inquiry_data *inq_data,
3963 struct scsi_sense_desc_header *header)
3964{
3965 struct scsi_sense_info *info;
3966
3967 info = (struct scsi_sense_info *)header;
3968
3969 scsi_info_sbuf(sb, cdb, cdb_len, inq_data, scsi_8btou64(info->info));
3970}
3971
3972void
3973scsi_sense_command_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
3974 u_int sense_len, uint8_t *cdb, int cdb_len,
3975 struct scsi_inquiry_data *inq_data,
3976 struct scsi_sense_desc_header *header)
3977{
3978 struct scsi_sense_command *command;
3979
3980 command = (struct scsi_sense_command *)header;
3981
3982 scsi_command_sbuf(sb, cdb, cdb_len, inq_data,
3983 scsi_8btou64(command->command_info));
3984}
3985
3986void
3987scsi_sense_sks_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
3988 u_int sense_len, uint8_t *cdb, int cdb_len,
3989 struct scsi_inquiry_data *inq_data,
3990 struct scsi_sense_desc_header *header)
3991{
3992 struct scsi_sense_sks *sks;
3993 int error_code, sense_key, asc, ascq;
3994
3995 sks = (struct scsi_sense_sks *)header;
3996
3997 scsi_extract_sense_len(sense, sense_len, &error_code, &sense_key,
3998 &asc, &ascq, /*show_errors*/ 1);
3999
4000 scsi_sks_sbuf(sb, sense_key, sks->sense_key_spec);
4001}
4002
4003void
4004scsi_sense_fru_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
4005 u_int sense_len, uint8_t *cdb, int cdb_len,
4006 struct scsi_inquiry_data *inq_data,
4007 struct scsi_sense_desc_header *header)
4008{
4009 struct scsi_sense_fru *fru;
4010
4011 fru = (struct scsi_sense_fru *)header;
4012
4013 scsi_fru_sbuf(sb, (uint64_t)fru->fru);
4014}
4015
4016void
4017scsi_sense_stream_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
4018 u_int sense_len, uint8_t *cdb, int cdb_len,
4019 struct scsi_inquiry_data *inq_data,
4020 struct scsi_sense_desc_header *header)
4021{
4022 struct scsi_sense_stream *stream;
4023 uint64_t info;
4024
4025 stream = (struct scsi_sense_stream *)header;
4026 info = 0;
4027
4028 scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &info, NULL);
4029
4030 scsi_stream_sbuf(sb, stream->byte3, info);
4031}
4032
4033void
4034scsi_sense_block_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
4035 u_int sense_len, uint8_t *cdb, int cdb_len,
4036 struct scsi_inquiry_data *inq_data,
4037 struct scsi_sense_desc_header *header)
4038{
4039 struct scsi_sense_block *block;
4040 uint64_t info;
4041
4042 block = (struct scsi_sense_block *)header;
4043 info = 0;
4044
4045 scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO, &info, NULL);
4046
4047 scsi_block_sbuf(sb, block->byte3, info);
4048}
4049
4050void
4051scsi_sense_progress_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
4052 u_int sense_len, uint8_t *cdb, int cdb_len,
4053 struct scsi_inquiry_data *inq_data,
4054 struct scsi_sense_desc_header *header)
4055{
4056 struct scsi_sense_progress *progress;
4057 const char *sense_key_desc;
4058 const char *asc_desc;
4059 int progress_val;
4060
4061 progress = (struct scsi_sense_progress *)header;
4062
4063 /*
4064 * Get descriptions for the sense key, ASC, and ASCQ in the
4065 * progress descriptor. These could be different than the values
4066 * in the overall sense data.
4067 */
4068 scsi_sense_desc(progress->sense_key, progress->add_sense_code,
4069 progress->add_sense_code_qual, inq_data,
4070 &sense_key_desc, &asc_desc);
4071
4072 progress_val = scsi_2btoul(progress->progress);
4073
4074 /*
4075 * The progress indicator is for the operation described by the
4076 * sense key, ASC, and ASCQ in the descriptor.
4077 */
4078 sbuf_cat(sb, sense_key_desc);
4079 sbuf_printf(sb, " asc:%x,%x (%s): ", progress->add_sense_code,
4080 progress->add_sense_code_qual, asc_desc);
4081 scsi_progress_sbuf(sb, progress_val);
4082}
4083
4084/*
4085 * Generic sense descriptor printing routine. This is used when we have
4086 * not yet implemented a specific printing routine for this descriptor.
4087 */
4088void
4089scsi_sense_generic_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
4090 u_int sense_len, uint8_t *cdb, int cdb_len,
4091 struct scsi_inquiry_data *inq_data,
4092 struct scsi_sense_desc_header *header)
4093{
4094 int i;
4095 uint8_t *buf_ptr;
4096
4097 sbuf_printf(sb, "Descriptor %#x:", header->desc_type);
4098
4099 buf_ptr = (uint8_t *)&header[1];
4100
4101 for (i = 0; i < header->length; i++, buf_ptr++)
4102 sbuf_printf(sb, " %02x", *buf_ptr);
4103}
4104
4105/*
4106 * Keep this list in numeric order. This speeds the array traversal.
4107 */
4108struct scsi_sense_desc_printer {
4109 uint8_t desc_type;
4110 /*
4111 * The function arguments here are the superset of what is needed
4112 * to print out various different descriptors. Command and
4113 * information descriptors need inquiry data and command type.
4114 * Sense key specific descriptors need the sense key.
4115 *
4116 * The sense, cdb, and inquiry data arguments may be NULL, but the
4117 * information printed may not be fully decoded as a result.
4118 */
4119 void (*print_func)(struct sbuf *sb, struct scsi_sense_data *sense,
4120 u_int sense_len, uint8_t *cdb, int cdb_len,
4121 struct scsi_inquiry_data *inq_data,
4122 struct scsi_sense_desc_header *header);
4123} scsi_sense_printers[] = {
4124 {SSD_DESC_INFO, scsi_sense_info_sbuf},
4125 {SSD_DESC_COMMAND, scsi_sense_command_sbuf},
4126 {SSD_DESC_SKS, scsi_sense_sks_sbuf},
4127 {SSD_DESC_FRU, scsi_sense_fru_sbuf},
4128 {SSD_DESC_STREAM, scsi_sense_stream_sbuf},
4129 {SSD_DESC_BLOCK, scsi_sense_block_sbuf},
4130 {SSD_DESC_PROGRESS, scsi_sense_progress_sbuf}
4131};
4132
4133void
4134scsi_sense_desc_sbuf(struct sbuf *sb, struct scsi_sense_data *sense,
4135 u_int sense_len, uint8_t *cdb, int cdb_len,
4136 struct scsi_inquiry_data *inq_data,
4137 struct scsi_sense_desc_header *header)
4138{
4139 int i, found;
4140
4141 for (i = 0, found = 0; i < (sizeof(scsi_sense_printers) /
4142 sizeof(scsi_sense_printers[0])); i++) {
4143 struct scsi_sense_desc_printer *printer;
4144
4145 printer = &scsi_sense_printers[i];
4146
4147 /*
4148 * The list is sorted, so quit if we've passed our
4149 * descriptor number.
4150 */
4151 if (printer->desc_type > header->desc_type)
4152 break;
4153
4154 if (printer->desc_type != header->desc_type)
4155 continue;
4156
4157 printer->print_func(sb, sense, sense_len, cdb, cdb_len,
4158 inq_data, header);
4159
4160 return;
4161 }
4162
4163 /*
4164 * No specific printing routine, so use the generic routine.
4165 */
4166 scsi_sense_generic_sbuf(sb, sense, sense_len, cdb, cdb_len,
4167 inq_data, header);
4168}
4169
4170scsi_sense_data_type
4171scsi_sense_type(struct scsi_sense_data *sense_data)
4172{
4173 switch (sense_data->error_code & SSD_ERRCODE) {
4174 case SSD_DESC_CURRENT_ERROR:
4175 case SSD_DESC_DEFERRED_ERROR:
4176 return (SSD_TYPE_DESC);
4177 break;
4178 case SSD_CURRENT_ERROR:
4179 case SSD_DEFERRED_ERROR:
4180 return (SSD_TYPE_FIXED);
4181 break;
4182 default:
4183 break;
4184 }
4185
4186 return (SSD_TYPE_NONE);
4187}
4188
4189struct scsi_print_sense_info {
4190 struct sbuf *sb;
4191 char *path_str;
4192 uint8_t *cdb;
4193 int cdb_len;
4194 struct scsi_inquiry_data *inq_data;
4195};
4196
4197static int
4198scsi_print_desc_func(struct scsi_sense_data_desc *sense, u_int sense_len,
4199 struct scsi_sense_desc_header *header, void *arg)
4200{
4201 struct scsi_print_sense_info *print_info;
4202
4203 print_info = (struct scsi_print_sense_info *)arg;
4204
4205 switch (header->desc_type) {
4206 case SSD_DESC_INFO:
4207 case SSD_DESC_FRU:
4208 case SSD_DESC_COMMAND:
4209 case SSD_DESC_SKS:
4210 case SSD_DESC_BLOCK:
4211 case SSD_DESC_STREAM:
4212 /*
4213 * We have already printed these descriptors, if they are
4214 * present.
4215 */
4216 break;
4217 default: {
4218 sbuf_printf(print_info->sb, "%s", print_info->path_str);
4219 scsi_sense_desc_sbuf(print_info->sb,
4220 (struct scsi_sense_data *)sense, sense_len,
4221 print_info->cdb, print_info->cdb_len,
4222 print_info->inq_data, header);
4223 sbuf_printf(print_info->sb, "\n");
4224 break;
4225 }
4226 }
4227
4228 /*
4229 * Tell the iterator that we want to see more descriptors if they
4230 * are present.
4231 */
4232 return (0);
4233}
4234
4235void
4236scsi_sense_only_sbuf(struct scsi_sense_data *sense, u_int sense_len,
4237 struct sbuf *sb, char *path_str,
4238 struct scsi_inquiry_data *inq_data, uint8_t *cdb,
4239 int cdb_len)
4240{
4241 int error_code, sense_key, asc, ascq;
4242
4243 sbuf_cat(sb, path_str);
4244
4245 scsi_extract_sense_len(sense, sense_len, &error_code, &sense_key,
4246 &asc, &ascq, /*show_errors*/ 1);
4247
4248 sbuf_printf(sb, "SCSI sense: ");
4249 switch (error_code) {
4250 case SSD_DEFERRED_ERROR:
4251 case SSD_DESC_DEFERRED_ERROR:
4252 sbuf_printf(sb, "Deferred error: ");
4253
4254 /* FALLTHROUGH */
4255 case SSD_CURRENT_ERROR:
4256 case SSD_DESC_CURRENT_ERROR:
4257 {
4258 struct scsi_sense_data_desc *desc_sense;
4259 struct scsi_print_sense_info print_info;
4260 const char *sense_key_desc;
4261 const char *asc_desc;
4262 uint8_t sks[3];
4263 uint64_t val;
4264 int info_valid;
4265
4266 /*
4267 * Get descriptions for the sense key, ASC, and ASCQ. If
4268 * these aren't present in the sense data (i.e. the sense
4269 * data isn't long enough), the -1 values that
4270 * scsi_extract_sense_len() returns will yield default
4271 * or error descriptions.
4272 */
4273 scsi_sense_desc(sense_key, asc, ascq, inq_data,
4274 &sense_key_desc, &asc_desc);
4275
4276 /*
4277 * We first print the sense key and ASC/ASCQ.
4278 */
4279 sbuf_cat(sb, sense_key_desc);
4280 sbuf_printf(sb, " asc:%x,%x (%s)\n", asc, ascq, asc_desc);
4281
4282 /*
4283 * Get the info field if it is valid.
4284 */
4285 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_INFO,
4286 &val, NULL) == 0)
4287 info_valid = 1;
4288 else
4289 info_valid = 0;
4290
4291 if (info_valid != 0) {
4292 uint8_t bits;
4293
4294 /*
4295 * Determine whether we have any block or stream
4296 * device-specific information.
4297 */
4298 if (scsi_get_block_info(sense, sense_len, inq_data,
4299 &bits) == 0) {
4300 sbuf_cat(sb, path_str);
4301 scsi_block_sbuf(sb, bits, val);
4302 sbuf_printf(sb, "\n");
4303 } else if (scsi_get_stream_info(sense, sense_len,
4304 inq_data, &bits) == 0) {
4305 sbuf_cat(sb, path_str);
4306 scsi_stream_sbuf(sb, bits, val);
4307 sbuf_printf(sb, "\n");
4308 } else if (val != 0) {
4309 /*
4310 * The information field can be valid but 0.
4311 * If the block or stream bits aren't set,
4312 * and this is 0, it isn't terribly useful
4313 * to print it out.
4314 */
4315 sbuf_cat(sb, path_str);
4316 scsi_info_sbuf(sb, cdb, cdb_len, inq_data, val);
4317 sbuf_printf(sb, "\n");
4318 }
4319 }
4320
4321 /*
4322 * Print the FRU.
4323 */
4324 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_FRU,
4325 &val, NULL) == 0) {
4326 sbuf_cat(sb, path_str);
4327 scsi_fru_sbuf(sb, val);
4328 sbuf_printf(sb, "\n");
4329 }
4330
4331 /*
4332 * Print any command-specific information.
4333 */
4334 if (scsi_get_sense_info(sense, sense_len, SSD_DESC_COMMAND,
4335 &val, NULL) == 0) {
4336 sbuf_cat(sb, path_str);
4337 scsi_command_sbuf(sb, cdb, cdb_len, inq_data, val);
4338 sbuf_printf(sb, "\n");
4339 }
4340
4341 /*
4342 * Print out any sense-key-specific information.
4343 */
4344 if (scsi_get_sks(sense, sense_len, sks) == 0) {
4345 sbuf_cat(sb, path_str);
4346 scsi_sks_sbuf(sb, sense_key, sks);
4347 sbuf_printf(sb, "\n");
4348 }
4349
4350 /*
4351 * If this is fixed sense, we're done. If we have
4352 * descriptor sense, we might have more information
4353 * available.
4354 */
4355 if (scsi_sense_type(sense) != SSD_TYPE_DESC)
4356 break;
4357
4358 desc_sense = (struct scsi_sense_data_desc *)sense;
4359
4360 print_info.sb = sb;
4361 print_info.path_str = path_str;
4362 print_info.cdb = cdb;
4363 print_info.cdb_len = cdb_len;
4364 print_info.inq_data = inq_data;
4365
4366 /*
4367 * Print any sense descriptors that we have not already printed.
4368 */
4369 scsi_desc_iterate(desc_sense, sense_len, scsi_print_desc_func,
4370 &print_info);
4371 break;
4372
4373 }
4374 case -1:
4375 /*
4376 * scsi_extract_sense_len() sets values to -1 if the
4377 * show_errors flag is set and they aren't present in the
4378 * sense data. This means that sense_len is 0.
4379 */
4380 sbuf_printf(sb, "No sense data present\n");
4381 break;
4382 default: {
4383 sbuf_printf(sb, "Error code 0x%x", error_code);
4384 if (sense->error_code & SSD_ERRCODE_VALID) {
4385 struct scsi_sense_data_fixed *fixed_sense;
4386
4387 fixed_sense = (struct scsi_sense_data_fixed *)sense;
4388
4389 if (SSD_FIXED_IS_PRESENT(fixed_sense, sense_len, info)){
4390 uint32_t info;
4391
4392 info = scsi_4btoul(fixed_sense->info);
4393
4394 sbuf_printf(sb, " at block no. %d (decimal)",
4395 info);
4396 }
4397 }
4398 sbuf_printf(sb, "\n");
4399 break;
4400 }
4401 }
4402}
4403
4404/*
3045 * scsi_sense_sbuf() returns 0 for success and -1 for failure.
3046 */
3047#ifdef _KERNEL
3048int
3049scsi_sense_sbuf(struct ccb_scsiio *csio, struct sbuf *sb,
3050 scsi_sense_string_flags flags)
3051#else /* !_KERNEL */
3052int
3053scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio,
3054 struct sbuf *sb, scsi_sense_string_flags flags)
3055#endif /* _KERNEL/!_KERNEL */
3056{
3057 struct scsi_sense_data *sense;
3058 struct scsi_inquiry_data *inq_data;
3059#ifdef _KERNEL
3060 struct ccb_getdev *cgd;
3061#endif /* _KERNEL */
4405 * scsi_sense_sbuf() returns 0 for success and -1 for failure.
4406 */
4407#ifdef _KERNEL
4408int
4409scsi_sense_sbuf(struct ccb_scsiio *csio, struct sbuf *sb,
4410 scsi_sense_string_flags flags)
4411#else /* !_KERNEL */
4412int
4413scsi_sense_sbuf(struct cam_device *device, struct ccb_scsiio *csio,
4414 struct sbuf *sb, scsi_sense_string_flags flags)
4415#endif /* _KERNEL/!_KERNEL */
4416{
4417 struct scsi_sense_data *sense;
4418 struct scsi_inquiry_data *inq_data;
4419#ifdef _KERNEL
4420 struct ccb_getdev *cgd;
4421#endif /* _KERNEL */
3062 u_int32_t info;
3063 int error_code;
3064 int sense_key;
3065 int asc, ascq;
3066 char path_str[64];
4422 char path_str[64];
4423 uint8_t *cdb;
3067
3068#ifndef _KERNEL
3069 if (device == NULL)
3070 return(-1);
3071#endif /* !_KERNEL */
3072 if ((csio == NULL) || (sb == NULL))
3073 return(-1);
3074

--- 81 unchanged lines hidden (view full) ---

3156#ifdef _KERNEL
3157 xpt_free_ccb((union ccb*)cgd);
3158#endif /* _KERNEL/!_KERNEL */
3159 return(-1);
3160 } else
3161 sense = &csio->sense_data;
3162 }
3163
4424
4425#ifndef _KERNEL
4426 if (device == NULL)
4427 return(-1);
4428#endif /* !_KERNEL */
4429 if ((csio == NULL) || (sb == NULL))
4430 return(-1);
4431

--- 81 unchanged lines hidden (view full) ---

4513#ifdef _KERNEL
4514 xpt_free_ccb((union ccb*)cgd);
4515#endif /* _KERNEL/!_KERNEL */
4516 return(-1);
4517 } else
4518 sense = &csio->sense_data;
4519 }
4520
4521 if (csio->ccb_h.flags & CAM_CDB_POINTER)
4522 cdb = csio->cdb_io.cdb_ptr;
4523 else
4524 cdb = csio->cdb_io.cdb_bytes;
3164
4525
3165 sbuf_cat(sb, path_str);
3166
3167 error_code = sense->error_code & SSD_ERRCODE;
3168 sense_key = sense->flags & SSD_KEY;
3169
3170 sbuf_printf(sb, "SCSI sense: ");
3171 switch (error_code) {
3172 case SSD_DEFERRED_ERROR:
3173 sbuf_printf(sb, "Deferred error: ");
3174
3175 /* FALLTHROUGH */
3176 case SSD_CURRENT_ERROR:
3177 {
3178 const char *sense_key_desc;
3179 const char *asc_desc;
3180
3181 asc = (sense->extra_len >= 5) ? sense->add_sense_code : 0;
3182 ascq = (sense->extra_len >= 6) ? sense->add_sense_code_qual : 0;
3183 scsi_sense_desc(sense_key, asc, ascq, inq_data,
3184 &sense_key_desc, &asc_desc);
3185 sbuf_cat(sb, sense_key_desc);
3186
3187 info = scsi_4btoul(sense->info);
3188
3189 if (sense->error_code & SSD_ERRCODE_VALID) {
3190
3191 switch (sense_key) {
3192 case SSD_KEY_NOT_READY:
3193 case SSD_KEY_ILLEGAL_REQUEST:
3194 case SSD_KEY_UNIT_ATTENTION:
3195 case SSD_KEY_DATA_PROTECT:
3196 break;
3197 case SSD_KEY_BLANK_CHECK:
3198 sbuf_printf(sb, " req sz: %d (decimal)", info);
3199 break;
3200 default:
3201 if (info) {
3202 if (sense->flags & SSD_ILI) {
3203 sbuf_printf(sb, " ILI (length "
3204 "mismatch): %d", info);
3205
3206 } else {
3207 sbuf_printf(sb, " info:%x",
3208 info);
3209 }
3210 }
3211 }
3212 } else if (info) {
3213 sbuf_printf(sb, " info?:%x", info);
3214 }
3215
3216 if (sense->extra_len >= 4) {
3217 if (bcmp(sense->cmd_spec_info, "\0\0\0\0", 4)) {
3218 sbuf_printf(sb, " csi:%x,%x,%x,%x",
3219 sense->cmd_spec_info[0],
3220 sense->cmd_spec_info[1],
3221 sense->cmd_spec_info[2],
3222 sense->cmd_spec_info[3]);
3223 }
3224 }
3225
3226 sbuf_printf(sb, " asc:%x,%x (%s)", asc, ascq, asc_desc);
3227
3228 if (sense->extra_len >= 7 && sense->fru) {
3229 sbuf_printf(sb, " field replaceable unit: %x",
3230 sense->fru);
3231 }
3232
3233 if ((sense->extra_len >= 10)
3234 && (sense->sense_key_spec[0] & SSD_SCS_VALID) != 0) {
3235 switch(sense_key) {
3236 case SSD_KEY_ILLEGAL_REQUEST: {
3237 int bad_command;
3238 char tmpstr2[40];
3239
3240 if (sense->sense_key_spec[0] & 0x40)
3241 bad_command = 1;
3242 else
3243 bad_command = 0;
3244
3245 tmpstr2[0] = '\0';
3246
3247 /* Bit pointer is valid */
3248 if (sense->sense_key_spec[0] & 0x08)
3249 snprintf(tmpstr2, sizeof(tmpstr2),
3250 "bit %d ",
3251 sense->sense_key_spec[0] & 0x7);
3252 sbuf_printf(sb, ": %s byte %d %sis invalid",
3253 bad_command ? "Command" : "Data",
3254 scsi_2btoul(
3255 &sense->sense_key_spec[1]),
3256 tmpstr2);
3257 break;
3258 }
3259 case SSD_KEY_RECOVERED_ERROR:
3260 case SSD_KEY_HARDWARE_ERROR:
3261 case SSD_KEY_MEDIUM_ERROR:
3262 sbuf_printf(sb, " actual retry count: %d",
3263 scsi_2btoul(
3264 &sense->sense_key_spec[1]));
3265 break;
3266 default:
3267 sbuf_printf(sb, " sks:%#x,%#x",
3268 sense->sense_key_spec[0],
3269 scsi_2btoul(
3270 &sense->sense_key_spec[1]));
3271 break;
3272 }
3273 }
3274 break;
3275
3276 }
3277 default:
3278 sbuf_printf(sb, "Error code 0x%x", sense->error_code);
3279 if (sense->error_code & SSD_ERRCODE_VALID) {
3280 sbuf_printf(sb, " at block no. %d (decimal)",
3281 info = scsi_4btoul(sense->info));
3282 }
3283 }
3284
3285 sbuf_printf(sb, "\n");
3286
4526 scsi_sense_only_sbuf(sense, csio->sense_len - csio->sense_resid, sb,
4527 path_str, inq_data, cdb, csio->cdb_len);
4528
3287#ifdef _KERNEL
3288 xpt_free_ccb((union ccb*)cgd);
3289#endif /* _KERNEL/!_KERNEL */
3290 return(0);
3291}
3292
3293
3294

--- 55 unchanged lines hidden (view full) ---

3350 sbuf_finish(&sb);
3351
3352 fprintf(ofile, "%s", sbuf_data(&sb));
3353}
3354
3355#endif /* _KERNEL/!_KERNEL */
3356
3357/*
4529#ifdef _KERNEL
4530 xpt_free_ccb((union ccb*)cgd);
4531#endif /* _KERNEL/!_KERNEL */
4532 return(0);
4533}
4534
4535
4536

--- 55 unchanged lines hidden (view full) ---

4592 sbuf_finish(&sb);
4593
4594 fprintf(ofile, "%s", sbuf_data(&sb));
4595}
4596
4597#endif /* _KERNEL/!_KERNEL */
4598
4599/*
4600 * Extract basic sense information. This is backward-compatible with the
4601 * previous implementation. For new implementations,
4602 * scsi_extract_sense_len() is recommended.
4603 */
4604void
4605scsi_extract_sense(struct scsi_sense_data *sense_data, int *error_code,
4606 int *sense_key, int *asc, int *ascq)
4607{
4608 scsi_extract_sense_len(sense_data, sizeof(*sense_data), error_code,
4609 sense_key, asc, ascq, /*show_errors*/ 0);
4610}
4611
4612/*
4613 * Extract basic sense information. If show_errors is set, sense values
4614 * will be set to -1 if they are not present.
4615 */
4616void
4617scsi_extract_sense_len(struct scsi_sense_data *sense_data, u_int sense_len,
4618 int *error_code, int *sense_key, int *asc, int *ascq,
4619 int show_errors)
4620{
4621 /*
4622 * If we have no length, we have no sense.
4623 */
4624 if (sense_len == 0) {
4625 if (show_errors == 0) {
4626 *error_code = 0;
4627 *sense_key = 0;
4628 *asc = 0;
4629 *ascq = 0;
4630 } else {
4631 *error_code = -1;
4632 *sense_key = -1;
4633 *asc = -1;
4634 *ascq = -1;
4635 }
4636 return;
4637 }
4638
4639 *error_code = sense_data->error_code & SSD_ERRCODE;
4640
4641 switch (*error_code) {
4642 case SSD_DESC_CURRENT_ERROR:
4643 case SSD_DESC_DEFERRED_ERROR: {
4644 struct scsi_sense_data_desc *sense;
4645
4646 sense = (struct scsi_sense_data_desc *)sense_data;
4647
4648 if (SSD_DESC_IS_PRESENT(sense, sense_len, sense_key))
4649 *sense_key = sense->sense_key & SSD_KEY;
4650 else
4651 *sense_key = (show_errors) ? -1 : 0;
4652
4653 if (SSD_DESC_IS_PRESENT(sense, sense_len, add_sense_code))
4654 *asc = sense->add_sense_code;
4655 else
4656 *asc = (show_errors) ? -1 : 0;
4657
4658 if (SSD_DESC_IS_PRESENT(sense, sense_len, add_sense_code_qual))
4659 *ascq = sense->add_sense_code_qual;
4660 else
4661 *ascq = (show_errors) ? -1 : 0;
4662 break;
4663 }
4664 case SSD_CURRENT_ERROR:
4665 case SSD_DEFERRED_ERROR:
4666 default: {
4667 struct scsi_sense_data_fixed *sense;
4668
4669 sense = (struct scsi_sense_data_fixed *)sense_data;
4670
4671 if (SSD_FIXED_IS_PRESENT(sense, sense_len, flags))
4672 *sense_key = sense->flags & SSD_KEY;
4673 else
4674 *sense_key = (show_errors) ? -1 : 0;
4675
4676 if ((SSD_FIXED_IS_PRESENT(sense, sense_len, add_sense_code))
4677 && (SSD_FIXED_IS_FILLED(sense, add_sense_code)))
4678 *asc = sense->add_sense_code;
4679 else
4680 *asc = (show_errors) ? -1 : 0;
4681
4682 if ((SSD_FIXED_IS_PRESENT(sense, sense_len,add_sense_code_qual))
4683 && (SSD_FIXED_IS_FILLED(sense, add_sense_code_qual)))
4684 *ascq = sense->add_sense_code_qual;
4685 else
4686 *ascq = (show_errors) ? -1 : 0;
4687 break;
4688 }
4689 }
4690}
4691
4692int
4693scsi_get_sense_key(struct scsi_sense_data *sense_data, u_int sense_len,
4694 int show_errors)
4695{
4696 int error_code, sense_key, asc, ascq;
4697
4698 scsi_extract_sense_len(sense_data, sense_len, &error_code,
4699 &sense_key, &asc, &ascq, show_errors);
4700
4701 return (sense_key);
4702}
4703
4704int
4705scsi_get_asc(struct scsi_sense_data *sense_data, u_int sense_len,
4706 int show_errors)
4707{
4708 int error_code, sense_key, asc, ascq;
4709
4710 scsi_extract_sense_len(sense_data, sense_len, &error_code,
4711 &sense_key, &asc, &ascq, show_errors);
4712
4713 return (asc);
4714}
4715
4716int
4717scsi_get_ascq(struct scsi_sense_data *sense_data, u_int sense_len,
4718 int show_errors)
4719{
4720 int error_code, sense_key, asc, ascq;
4721
4722 scsi_extract_sense_len(sense_data, sense_len, &error_code,
4723 &sense_key, &asc, &ascq, show_errors);
4724
4725 return (ascq);
4726}
4727
4728/*
3358 * This function currently requires at least 36 bytes, or
3359 * SHORT_INQUIRY_LENGTH, worth of data to function properly. If this
3360 * function needs more or less data in the future, another length should be
3361 * defined in scsi_all.h to indicate the minimum amount of data necessary
3362 * for this routine to function properly.
3363 */
3364void
3365scsi_print_inquiry(struct scsi_inquiry_data *inq_data)

--- 1111 unchanged lines hidden ---
4729 * This function currently requires at least 36 bytes, or
4730 * SHORT_INQUIRY_LENGTH, worth of data to function properly. If this
4731 * function needs more or less data in the future, another length should be
4732 * defined in scsi_all.h to indicate the minimum amount of data necessary
4733 * for this routine to function properly.
4734 */
4735void
4736scsi_print_inquiry(struct scsi_inquiry_data *inq_data)

--- 1111 unchanged lines hidden ---