Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SCSI] libosd: SCSI/OSD Sense decoding support

Implementation of the osd_req_decode_sense() API. Can be called by
library users to decode what failed in command executions.

Add SCSI_OSD_DPRINT_SENSE Kconfig variable. Possible values are:
0 - Do not print any errors to messages file <KERN_ERR>
1 - (Default) Print only decoded errors that are not recoverable.
Recoverable errors are those that the target has complied with
the request but with a warning. For example read passed end of
object will return zeros after the last valid byte.
2- Print all errors.

Signed-off-by: Boaz Harrosh <bharrosh@panasas.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

authored by

Boaz Harrosh and committed by
James Bottomley
98f3aea2 1b9dce94

+506
+6
drivers/scsi/osd/Kbuild
··· 20 20 CONFIG_SCSI_OSD_ULD=m 21 21 ccflags-y += -DCONFIG_SCSI_OSD_ULD -DCONFIG_SCSI_OSD_ULD_MODULE 22 22 23 + # CONFIG_SCSI_OSD_DPRINT_SENSE = 24 + # 0 - no print of errors 25 + # 1 - print errors 26 + # 2 - errors + warrnings 27 + ccflags-y += -DCONFIG_SCSI_OSD_DPRINT_SENSE=1 28 + 23 29 # Uncomment to turn debug on 24 30 # ccflags-y += -DCONFIG_SCSI_OSD_DEBUG 25 31
+191
drivers/scsi/osd/osd_initiator.c
··· 42 42 #include <scsi/osd_initiator.h> 43 43 #include <scsi/osd_sec.h> 44 44 #include <scsi/osd_attributes.h> 45 + #include <scsi/osd_sense.h> 46 + 45 47 #include <scsi/scsi_device.h> 46 48 47 49 #include "osd_debug.h" ··· 1340 1338 return 0; 1341 1339 } 1342 1340 EXPORT_SYMBOL(osd_finalize_request); 1341 + 1342 + #define OSD_SENSE_PRINT1(fmt, a...) \ 1343 + do { \ 1344 + if (__cur_sense_need_output) \ 1345 + OSD_ERR(fmt, ##a); \ 1346 + } while (0) 1347 + 1348 + #define OSD_SENSE_PRINT2(fmt, a...) OSD_SENSE_PRINT1(" " fmt, ##a) 1349 + 1350 + int osd_req_decode_sense_full(struct osd_request *or, 1351 + struct osd_sense_info *osi, bool silent, 1352 + struct osd_obj_id *bad_obj_list __unused, int max_obj __unused, 1353 + struct osd_attr *bad_attr_list, int max_attr) 1354 + { 1355 + int sense_len, original_sense_len; 1356 + struct osd_sense_info local_osi; 1357 + struct scsi_sense_descriptor_based *ssdb; 1358 + void *cur_descriptor; 1359 + #if (CONFIG_SCSI_OSD_DPRINT_SENSE == 0) 1360 + const bool __cur_sense_need_output = false; 1361 + #else 1362 + bool __cur_sense_need_output = !silent; 1363 + #endif 1364 + 1365 + if (!or->request->errors) 1366 + return 0; 1367 + 1368 + ssdb = or->request->sense; 1369 + sense_len = or->request->sense_len; 1370 + if ((sense_len < (int)sizeof(*ssdb) || !ssdb->sense_key)) { 1371 + OSD_ERR("Block-layer returned error(0x%x) but " 1372 + "sense_len(%u) || key(%d) is empty\n", 1373 + or->request->errors, sense_len, ssdb->sense_key); 1374 + return -EIO; 1375 + } 1376 + 1377 + if ((ssdb->response_code != 0x72) && (ssdb->response_code != 0x73)) { 1378 + OSD_ERR("Unrecognized scsi sense: rcode=%x length=%d\n", 1379 + ssdb->response_code, sense_len); 1380 + return -EIO; 1381 + } 1382 + 1383 + osi = osi ? : &local_osi; 1384 + memset(osi, 0, sizeof(*osi)); 1385 + osi->key = ssdb->sense_key; 1386 + osi->additional_code = be16_to_cpu(ssdb->additional_sense_code); 1387 + original_sense_len = ssdb->additional_sense_length + 8; 1388 + 1389 + #if (CONFIG_SCSI_OSD_DPRINT_SENSE == 1) 1390 + if (__cur_sense_need_output) 1391 + __cur_sense_need_output = (osi->key > scsi_sk_recovered_error); 1392 + #endif 1393 + OSD_SENSE_PRINT1("Main Sense information key=0x%x length(%d, %d) " 1394 + "additional_code=0x%x\n", 1395 + osi->key, original_sense_len, sense_len, 1396 + osi->additional_code); 1397 + 1398 + if (original_sense_len < sense_len) 1399 + sense_len = original_sense_len; 1400 + 1401 + cur_descriptor = ssdb->ssd; 1402 + sense_len -= sizeof(*ssdb); 1403 + while (sense_len > 0) { 1404 + struct scsi_sense_descriptor *ssd = cur_descriptor; 1405 + int cur_len = ssd->additional_length + 2; 1406 + 1407 + sense_len -= cur_len; 1408 + 1409 + if (sense_len < 0) 1410 + break; /* sense was truncated */ 1411 + 1412 + switch (ssd->descriptor_type) { 1413 + case scsi_sense_information: 1414 + case scsi_sense_command_specific_information: 1415 + { 1416 + struct scsi_sense_command_specific_data_descriptor 1417 + *sscd = cur_descriptor; 1418 + 1419 + osi->command_info = 1420 + get_unaligned_be64(&sscd->information) ; 1421 + OSD_SENSE_PRINT2( 1422 + "command_specific_information 0x%llx \n", 1423 + _LLU(osi->command_info)); 1424 + break; 1425 + } 1426 + case scsi_sense_key_specific: 1427 + { 1428 + struct scsi_sense_key_specific_data_descriptor 1429 + *ssks = cur_descriptor; 1430 + 1431 + osi->sense_info = get_unaligned_be16(&ssks->value); 1432 + OSD_SENSE_PRINT2( 1433 + "sense_key_specific_information %u" 1434 + "sksv_cd_bpv_bp (0x%x)\n", 1435 + osi->sense_info, ssks->sksv_cd_bpv_bp); 1436 + break; 1437 + } 1438 + case osd_sense_object_identification: 1439 + { /*FIXME: Keep first not last, Store in array*/ 1440 + struct osd_sense_identification_data_descriptor 1441 + *osidd = cur_descriptor; 1442 + 1443 + osi->not_initiated_command_functions = 1444 + le32_to_cpu(osidd->not_initiated_functions); 1445 + osi->completed_command_functions = 1446 + le32_to_cpu(osidd->completed_functions); 1447 + osi->obj.partition = be64_to_cpu(osidd->partition_id); 1448 + osi->obj.id = be64_to_cpu(osidd->object_id); 1449 + OSD_SENSE_PRINT2( 1450 + "object_identification pid=0x%llx oid=0x%llx\n", 1451 + _LLU(osi->obj.partition), _LLU(osi->obj.id)); 1452 + OSD_SENSE_PRINT2( 1453 + "not_initiated_bits(%x) " 1454 + "completed_command_bits(%x)\n", 1455 + osi->not_initiated_command_functions, 1456 + osi->completed_command_functions); 1457 + break; 1458 + } 1459 + case osd_sense_response_integrity_check: 1460 + { 1461 + struct osd_sense_response_integrity_check_descriptor 1462 + *osricd = cur_descriptor; 1463 + const unsigned len = 1464 + sizeof(osricd->integrity_check_value); 1465 + char key_dump[len*4 + 2]; /* 2nibbles+space+ASCII */ 1466 + 1467 + hex_dump_to_buffer(osricd->integrity_check_value, len, 1468 + 32, 1, key_dump, sizeof(key_dump), true); 1469 + OSD_SENSE_PRINT2("response_integrity [%s]\n", key_dump); 1470 + } 1471 + case osd_sense_attribute_identification: 1472 + { 1473 + struct osd_sense_attributes_data_descriptor 1474 + *osadd = cur_descriptor; 1475 + int len = min(cur_len, sense_len); 1476 + int i = 0; 1477 + struct osd_sense_attr *pattr = osadd->sense_attrs; 1478 + 1479 + while (len < 0) { 1480 + u32 attr_page = be32_to_cpu(pattr->attr_page); 1481 + u32 attr_id = be32_to_cpu(pattr->attr_id); 1482 + 1483 + if (i++ == 0) { 1484 + osi->attr.attr_page = attr_page; 1485 + osi->attr.attr_id = attr_id; 1486 + } 1487 + 1488 + if (bad_attr_list && max_attr) { 1489 + bad_attr_list->attr_page = attr_page; 1490 + bad_attr_list->attr_id = attr_id; 1491 + bad_attr_list++; 1492 + max_attr--; 1493 + } 1494 + OSD_SENSE_PRINT2( 1495 + "osd_sense_attribute_identification" 1496 + "attr_page=0x%x attr_id=0x%x\n", 1497 + attr_page, attr_id); 1498 + } 1499 + } 1500 + /*These are not legal for OSD*/ 1501 + case scsi_sense_field_replaceable_unit: 1502 + OSD_SENSE_PRINT2("scsi_sense_field_replaceable_unit\n"); 1503 + break; 1504 + case scsi_sense_stream_commands: 1505 + OSD_SENSE_PRINT2("scsi_sense_stream_commands\n"); 1506 + break; 1507 + case scsi_sense_block_commands: 1508 + OSD_SENSE_PRINT2("scsi_sense_block_commands\n"); 1509 + break; 1510 + case scsi_sense_ata_return: 1511 + OSD_SENSE_PRINT2("scsi_sense_ata_return\n"); 1512 + break; 1513 + default: 1514 + if (ssd->descriptor_type <= scsi_sense_Reserved_last) 1515 + OSD_SENSE_PRINT2( 1516 + "scsi_sense Reserved descriptor (0x%x)", 1517 + ssd->descriptor_type); 1518 + else 1519 + OSD_SENSE_PRINT2( 1520 + "scsi_sense Vendor descriptor (0x%x)", 1521 + ssd->descriptor_type); 1522 + } 1523 + 1524 + cur_descriptor += cur_len; 1525 + } 1526 + 1527 + return (osi->key > scsi_sk_recovered_error) ? -EIO : 0; 1528 + } 1529 + EXPORT_SYMBOL(osd_req_decode_sense_full); 1343 1530 1344 1531 /* 1345 1532 * Implementation of osd_sec.h API
+49
include/scsi/osd_initiator.h
··· 217 217 osd_req_done_fn *done, void *private); 218 218 219 219 /** 220 + * osd_req_decode_sense_full - Decode sense information after execution. 221 + * 222 + * @or: - osd_request to examine 223 + * @osi - Recievs a more detailed error report information (optional). 224 + * @silent - Do not print to dmsg (Even if enabled) 225 + * @bad_obj_list - Some commands act on multiple objects. Failed objects will 226 + * be recieved here (optional) 227 + * @max_obj - Size of @bad_obj_list. 228 + * @bad_attr_list - List of failing attributes (optional) 229 + * @max_attr - Size of @bad_attr_list. 230 + * 231 + * After execution, sense + return code can be analyzed using this function. The 232 + * return code is the final disposition on the error. So it is possible that a 233 + * CHECK_CONDITION was returned from target but this will return NO_ERROR, for 234 + * example on recovered errors. All parameters are optional if caller does 235 + * not need any returned information. 236 + * Note: This function will also dump the error to dmsg according to settings 237 + * of the SCSI_OSD_DPRINT_SENSE Kconfig value. Set @silent if you know the 238 + * command would routinely fail, to not spam the dmsg file. 239 + */ 240 + struct osd_sense_info { 241 + int key; /* one of enum scsi_sense_keys */ 242 + int additional_code ; /* enum osd_additional_sense_codes */ 243 + union { /* Sense specific information */ 244 + u16 sense_info; 245 + u16 cdb_field_offset; /* scsi_invalid_field_in_cdb */ 246 + }; 247 + union { /* Command specific information */ 248 + u64 command_info; 249 + }; 250 + 251 + u32 not_initiated_command_functions; /* osd_command_functions_bits */ 252 + u32 completed_command_functions; /* osd_command_functions_bits */ 253 + struct osd_obj_id obj; 254 + struct osd_attr attr; 255 + }; 256 + 257 + int osd_req_decode_sense_full(struct osd_request *or, 258 + struct osd_sense_info *osi, bool silent, 259 + struct osd_obj_id *bad_obj_list, int max_obj, 260 + struct osd_attr *bad_attr_list, int max_attr); 261 + 262 + static inline int osd_req_decode_sense(struct osd_request *or, 263 + struct osd_sense_info *osi) 264 + { 265 + return osd_req_decode_sense_full(or, osi, false, NULL, 0, NULL, 0); 266 + } 267 + 268 + /** 220 269 * osd_end_request - return osd_request to free store 221 270 * 222 271 * @or: osd_request to free
+260
include/scsi/osd_sense.h
··· 1 + /* 2 + * osd_sense.h - OSD Related sense handling definitions. 3 + * 4 + * Copyright (C) 2008 Panasas Inc. All rights reserved. 5 + * 6 + * Authors: 7 + * Boaz Harrosh <bharrosh@panasas.com> 8 + * Benny Halevy <bhalevy@panasas.com> 9 + * 10 + * This program is free software; you can redistribute it and/or modify 11 + * it under the terms of the GNU General Public License version 2 12 + * 13 + * This file contains types and constants that are defined by the protocol 14 + * Note: All names and symbols are taken from the OSD standard's text. 15 + */ 16 + #ifndef __OSD_SENSE_H__ 17 + #define __OSD_SENSE_H__ 18 + 19 + #include <scsi/osd_protocol.h> 20 + 21 + /* SPC3r23 4.5.6 Sense key and sense code definitions table 27 */ 22 + enum scsi_sense_keys { 23 + scsi_sk_no_sense = 0x0, 24 + scsi_sk_recovered_error = 0x1, 25 + scsi_sk_not_ready = 0x2, 26 + scsi_sk_medium_error = 0x3, 27 + scsi_sk_hardware_error = 0x4, 28 + scsi_sk_illegal_request = 0x5, 29 + scsi_sk_unit_attention = 0x6, 30 + scsi_sk_data_protect = 0x7, 31 + scsi_sk_blank_check = 0x8, 32 + scsi_sk_vendor_specific = 0x9, 33 + scsi_sk_copy_aborted = 0xa, 34 + scsi_sk_aborted_command = 0xb, 35 + scsi_sk_volume_overflow = 0xd, 36 + scsi_sk_miscompare = 0xe, 37 + scsi_sk_reserved = 0xf, 38 + }; 39 + 40 + /* SPC3r23 4.5.6 Sense key and sense code definitions table 28 */ 41 + /* Note: only those which can be returned by an OSD target. Most of 42 + * these errors are taken care of by the generic scsi layer. 43 + */ 44 + enum osd_additional_sense_codes { 45 + scsi_no_additional_sense_information = 0x0000, 46 + scsi_operation_in_progress = 0x0016, 47 + scsi_cleaning_requested = 0x0017, 48 + scsi_lunr_cause_not_reportable = 0x0400, 49 + scsi_logical_unit_is_in_process_of_becoming_ready = 0x0401, 50 + scsi_lunr_initializing_command_required = 0x0402, 51 + scsi_lunr_manual_intervention_required = 0x0403, 52 + scsi_lunr_operation_in_progress = 0x0407, 53 + scsi_lunr_selftest_in_progress = 0x0409, 54 + scsi_luna_asymmetric_access_state_transition = 0x040a, 55 + scsi_luna_target_port_in_standby_state = 0x040b, 56 + scsi_luna_target_port_in_unavailable_state = 0x040c, 57 + scsi_lunr_notify_enable_spinup_required = 0x0411, 58 + scsi_logical_unit_does_not_respond_to_selection = 0x0500, 59 + scsi_logical_unit_communication_failure = 0x0800, 60 + scsi_logical_unit_communication_timeout = 0x0801, 61 + scsi_logical_unit_communication_parity_error = 0x0802, 62 + scsi_error_log_overflow = 0x0a00, 63 + scsi_warning = 0x0b00, 64 + scsi_warning_specified_temperature_exceeded = 0x0b01, 65 + scsi_warning_enclosure_degraded = 0x0b02, 66 + scsi_write_error_unexpected_unsolicited_data = 0x0c0c, 67 + scsi_write_error_not_enough_unsolicited_data = 0x0c0d, 68 + scsi_invalid_information_unit = 0x0e00, 69 + scsi_invalid_field_in_command_information_unit = 0x0e03, 70 + scsi_read_error_failed_retransmission_request = 0x1113, 71 + scsi_parameter_list_length_error = 0x1a00, 72 + scsi_invalid_command_operation_code = 0x2000, 73 + scsi_invalid_field_in_cdb = 0x2400, 74 + osd_security_audit_value_frozen = 0x2404, 75 + osd_security_working_key_frozen = 0x2405, 76 + osd_nonce_not_unique = 0x2406, 77 + osd_nonce_timestamp_out_of_range = 0x2407, 78 + scsi_logical_unit_not_supported = 0x2500, 79 + scsi_invalid_field_in_parameter_list = 0x2600, 80 + scsi_parameter_not_supported = 0x2601, 81 + scsi_parameter_value_invalid = 0x2602, 82 + scsi_invalid_release_of_persistent_reservation = 0x2604, 83 + osd_invalid_dataout_buffer_integrity_check_value = 0x260f, 84 + scsi_not_ready_to_ready_change_medium_may_have_changed = 0x2800, 85 + scsi_power_on_reset_or_bus_device_reset_occurred = 0x2900, 86 + scsi_power_on_occurred = 0x2901, 87 + scsi_scsi_bus_reset_occurred = 0x2902, 88 + scsi_bus_device_reset_function_occurred = 0x2903, 89 + scsi_device_internal_reset = 0x2904, 90 + scsi_transceiver_mode_changed_to_single_ended = 0x2905, 91 + scsi_transceiver_mode_changed_to_lvd = 0x2906, 92 + scsi_i_t_nexus_loss_occurred = 0x2907, 93 + scsi_parameters_changed = 0x2a00, 94 + scsi_mode_parameters_changed = 0x2a01, 95 + scsi_asymmetric_access_state_changed = 0x2a06, 96 + scsi_priority_changed = 0x2a08, 97 + scsi_command_sequence_error = 0x2c00, 98 + scsi_previous_busy_status = 0x2c07, 99 + scsi_previous_task_set_full_status = 0x2c08, 100 + scsi_previous_reservation_conflict_status = 0x2c09, 101 + osd_partition_or_collection_contains_user_objects = 0x2c0a, 102 + scsi_commands_cleared_by_another_initiator = 0x2f00, 103 + scsi_cleaning_failure = 0x3007, 104 + scsi_enclosure_failure = 0x3400, 105 + scsi_enclosure_services_failure = 0x3500, 106 + scsi_unsupported_enclosure_function = 0x3501, 107 + scsi_enclosure_services_unavailable = 0x3502, 108 + scsi_enclosure_services_transfer_failure = 0x3503, 109 + scsi_enclosure_services_transfer_refused = 0x3504, 110 + scsi_enclosure_services_checksum_error = 0x3505, 111 + scsi_rounded_parameter = 0x3700, 112 + osd_read_past_end_of_user_object = 0x3b17, 113 + scsi_logical_unit_has_not_self_configured_yet = 0x3e00, 114 + scsi_logical_unit_failure = 0x3e01, 115 + scsi_timeout_on_logical_unit = 0x3e02, 116 + scsi_logical_unit_failed_selftest = 0x3e03, 117 + scsi_logical_unit_unable_to_update_selftest_log = 0x3e04, 118 + scsi_target_operating_conditions_have_changed = 0x3f00, 119 + scsi_microcode_has_been_changed = 0x3f01, 120 + scsi_inquiry_data_has_changed = 0x3f03, 121 + scsi_echo_buffer_overwritten = 0x3f0f, 122 + scsi_diagnostic_failure_on_component_nn_first = 0x4080, 123 + scsi_diagnostic_failure_on_component_nn_last = 0x40ff, 124 + scsi_message_error = 0x4300, 125 + scsi_internal_target_failure = 0x4400, 126 + scsi_select_or_reselect_failure = 0x4500, 127 + scsi_scsi_parity_error = 0x4700, 128 + scsi_data_phase_crc_error_detected = 0x4701, 129 + scsi_scsi_parity_error_detected_during_st_data_phase = 0x4702, 130 + scsi_asynchronous_information_protection_error_detected = 0x4704, 131 + scsi_protocol_service_crc_error = 0x4705, 132 + scsi_phy_test_function_in_progress = 0x4706, 133 + scsi_invalid_message_error = 0x4900, 134 + scsi_command_phase_error = 0x4a00, 135 + scsi_data_phase_error = 0x4b00, 136 + scsi_logical_unit_failed_self_configuration = 0x4c00, 137 + scsi_overlapped_commands_attempted = 0x4e00, 138 + osd_quota_error = 0x5507, 139 + scsi_failure_prediction_threshold_exceeded = 0x5d00, 140 + scsi_failure_prediction_threshold_exceeded_false = 0x5dff, 141 + scsi_voltage_fault = 0x6500, 142 + }; 143 + 144 + enum scsi_descriptor_types { 145 + scsi_sense_information = 0x0, 146 + scsi_sense_command_specific_information = 0x1, 147 + scsi_sense_key_specific = 0x2, 148 + scsi_sense_field_replaceable_unit = 0x3, 149 + scsi_sense_stream_commands = 0x4, 150 + scsi_sense_block_commands = 0x5, 151 + osd_sense_object_identification = 0x6, 152 + osd_sense_response_integrity_check = 0x7, 153 + osd_sense_attribute_identification = 0x8, 154 + scsi_sense_ata_return = 0x9, 155 + 156 + scsi_sense_Reserved_first = 0x0A, 157 + scsi_sense_Reserved_last = 0x7F, 158 + scsi_sense_Vendor_specific_first = 0x80, 159 + scsi_sense_Vendor_specific_last = 0xFF, 160 + }; 161 + 162 + struct scsi_sense_descriptor { /* for picking into desc type */ 163 + u8 descriptor_type; /* one of enum scsi_descriptor_types */ 164 + u8 additional_length; /* n - 1 */ 165 + u8 data[]; 166 + } __packed; 167 + 168 + /* OSD deploys only scsi descriptor_based sense buffers */ 169 + struct scsi_sense_descriptor_based { 170 + /*0*/ u8 response_code; /* 0x72 or 0x73 */ 171 + /*1*/ u8 sense_key; /* one of enum scsi_sense_keys (4 lower bits) */ 172 + /*2*/ __be16 additional_sense_code; /* enum osd_additional_sense_codes */ 173 + /*4*/ u8 Reserved[3]; 174 + /*7*/ u8 additional_sense_length; /* n - 7 */ 175 + /*8*/ struct scsi_sense_descriptor ssd[0]; /* variable length, 1 or more */ 176 + } __packed; 177 + 178 + /* some descriptors deployed by OSD */ 179 + 180 + /* SPC3r23 4.5.2.3 Command-specific information sense data descriptor */ 181 + /* Note: this is the same for descriptor_type=00 but with type=00 the 182 + * Reserved[0] == 0x80 (ie. bit-7 set) 183 + */ 184 + struct scsi_sense_command_specific_data_descriptor { 185 + /*0*/ u8 descriptor_type; /* (00h/01h) */ 186 + /*1*/ u8 additional_length; /* (0Ah) */ 187 + /*2*/ u8 Reserved[2]; 188 + /*4*/ __be64 information; 189 + } __packed; 190 + /*12*/ 191 + 192 + struct scsi_sense_key_specific_data_descriptor { 193 + /*0*/ u8 descriptor_type; /* (02h) */ 194 + /*1*/ u8 additional_length; /* (06h) */ 195 + /*2*/ u8 Reserved[2]; 196 + /* SKSV, C/D, Reserved (2), BPV, BIT POINTER (3) */ 197 + /*4*/ u8 sksv_cd_bpv_bp; 198 + /*5*/ __be16 value; /* field-pointer/progress-value/retry-count/... */ 199 + /*7*/ u8 Reserved2; 200 + } __packed; 201 + /*8*/ 202 + 203 + /* 4.16.2.1 OSD error identification sense data descriptor - table 52 */ 204 + /* Note: these bits are defined LE order for easy definition, this way the BIT() 205 + * number is the same as in the documentation. Below members at 206 + * osd_sense_identification_data_descriptor are therefore defined __le32. 207 + */ 208 + enum osd_command_functions_bits { 209 + OSD_CFB_COMMAND = BIT(4), 210 + OSD_CFB_CMD_CAP_VERIFIED = BIT(5), 211 + OSD_CFB_VALIDATION = BIT(7), 212 + OSD_CFB_IMP_ST_ATT = BIT(12), 213 + OSD_CFB_SET_ATT = BIT(20), 214 + OSD_CFB_SA_CAP_VERIFIED = BIT(21), 215 + OSD_CFB_GET_ATT = BIT(28), 216 + OSD_CFB_GA_CAP_VERIFIED = BIT(29), 217 + }; 218 + 219 + struct osd_sense_identification_data_descriptor { 220 + /*0*/ u8 descriptor_type; /* (06h) */ 221 + /*1*/ u8 additional_length; /* (1Eh) */ 222 + /*2*/ u8 Reserved[6]; 223 + /*8*/ __le32 not_initiated_functions; /*osd_command_functions_bits*/ 224 + /*12*/ __le32 completed_functions; /*osd_command_functions_bits*/ 225 + /*16*/ __be64 partition_id; 226 + /*24*/ __be64 object_id; 227 + } __packed; 228 + /*32*/ 229 + 230 + struct osd_sense_response_integrity_check_descriptor { 231 + /*0*/ u8 descriptor_type; /* (07h) */ 232 + /*1*/ u8 additional_length; /* (20h) */ 233 + /*2*/ u8 integrity_check_value[32]; /*FIXME: OSDv2_CRYPTO_KEYID_SIZE*/ 234 + } __packed; 235 + /*34*/ 236 + 237 + struct osd_sense_attributes_data_descriptor { 238 + /*0*/ u8 descriptor_type; /* (08h) */ 239 + /*1*/ u8 additional_length; /* (n-2) */ 240 + /*2*/ u8 Reserved[6]; 241 + struct osd_sense_attr { 242 + /*8*/ __be32 attr_page; 243 + /*12*/ __be32 attr_id; 244 + /*16*/ } sense_attrs[0]; /* 1 or more */ 245 + } __packed; 246 + /*variable*/ 247 + 248 + /* Dig into scsi_sk_illegal_request/scsi_invalid_field_in_cdb errors */ 249 + 250 + /*FIXME: Support also field in CAPS*/ 251 + #define OSD_CDB_OFFSET(F) offsetof(struct osd_cdb_head, F) 252 + 253 + enum osdv2_cdb_field_offset { 254 + OSDv1_CFO_STARTING_BYTE = OSD_CDB_OFFSET(v1.start_address), 255 + OSD_CFO_STARTING_BYTE = OSD_CDB_OFFSET(v2.start_address), 256 + OSD_CFO_PARTITION_ID = OSD_CDB_OFFSET(partition), 257 + OSD_CFO_OBJECT_ID = OSD_CDB_OFFSET(object), 258 + }; 259 + 260 + #endif /* ndef __OSD_SENSE_H__ */