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 --- |