/* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2018 Nexenta Systems, Inc. */ #ifndef _SMARTPQI_HW_H #define _SMARTPQI_HW_H #ifdef __cplusplus extern "C" { #endif #include #include /* ---- for submission of legacy SIS commands ---- */ #define SIS_REENABLE_SIS_MODE 0x1 #define SIS_ENABLE_MSIX 0x40 #define SIS_ENABLE_INTX 0x80 #define SIS_SOFT_RESET 0x100 #define SIS_TRIGGER_SHUTDOWN 0x800000 #define SIS_CMD_READY 0x200 #define SIS_CMD_COMPLETE 0x1000 #define SIS_CLEAR_CTRL_TO_HOST_DOORBELL 0x1000 #define SIS_CMD_STATUS_SUCCESS 0x1 #define SIS_CMD_COMPLETE_TIMEOUT_SECS 30 #define SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS 10 /* ---- SOP data direction flags ---- */ #define SOP_NO_DIRECTION_FLAG 0 #define SOP_WRITE_FLAG 1 /* host writes data to Data-Out */ /* buffer */ #define SOP_READ_FLAG 2 /* host receives data from Data-In */ /* buffer */ #define SOP_BIDIRECTIONAL 3 /* data is transferred from the */ /* Data-Out buffer and data is */ /* transferred to the Data-In buffer */ #define SOP_TASK_ATTRIBUTE_SIMPLE 0 #define SOP_TASK_ATTRIBUTE_HEAD_OF_QUEUE 1 #define SOP_TASK_ATTRIBUTE_ORDERED 2 #define SOP_TASK_ATTRIBUTE_ACA 4 #define SOP_TMF_COMPLETE 0x0 #define SOP_TMF_FUNCTION_SUCCEEDED 0x8 #define SOP_TASK_MANAGEMENT_LUN_RESET 0x08 /* ---- CISS commands ---- */ #define CISS_READ 0xc0 #define CISS_REPORT_LOG 0xc2 #define CISS_REPORT_PHYS 0xc3 #define CISS_GET_RAID_MAP 0xc8 /* constants for CISS_REPORT_LOG/CISS_REPORT_PHYS commands */ #define CISS_REPORT_LOG_EXTENDED 0x1 #define CISS_REPORT_PHYS_EXTENDED 0x2 /* BMIC commands */ #define BMIC_IDENTIFY_CONTROLLER 0x11 #define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15 #define BMIC_READ 0x26 #define BMIC_WRITE 0x27 #define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64 #define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66 #define BMIC_WRITE_HOST_WELLNESS 0xa5 #define BMIC_CACHE_FLUSH 0xc2 #define PQI_DATA_IN_OUT_GOOD 0x0 #define PQI_DATA_IN_OUT_UNDERFLOW 0x1 #define PQI_DATA_IN_OUT_BUFFER_ERROR 0x40 #define PQI_DATA_IN_OUT_BUFFER_OVERFLOW 0x41 #define PQI_DATA_IN_OUT_BUFFER_OVERFLOW_DESCRIPTOR_AREA 0x42 #define PQI_DATA_IN_OUT_BUFFER_OVERFLOW_BRIDGE 0x43 #define PQI_DATA_IN_OUT_PCIE_FABRIC_ERROR 0x60 #define PQI_DATA_IN_OUT_PCIE_COMPLETION_TIMEOUT 0x61 #define PQI_DATA_IN_OUT_PCIE_COMPLETER_ABORT_RECEIVED 0x62 #define PQI_DATA_IN_OUT_PCIE_UNSUPPORTED_REQUEST_RECEIVED 0x63 #define PQI_DATA_IN_OUT_PCIE_ECRC_CHECK_FAILED 0x64 #define PQI_DATA_IN_OUT_PCIE_UNSUPPORTED_REQUEST 0x65 #define PQI_DATA_IN_OUT_PCIE_ACS_VIOLATION 0x66 #define PQI_DATA_IN_OUT_PCIE_TLP_PREFIX_BLOCKED 0x67 #define PQI_DATA_IN_OUT_PCIE_POISONED_MEMORY_READ 0x6F #define PQI_DATA_IN_OUT_ERROR 0xf0 #define PQI_DATA_IN_OUT_PROTOCOL_ERROR 0xf1 #define PQI_DATA_IN_OUT_HARDWARE_ERROR 0xf2 #define PQI_DATA_IN_OUT_UNSOLICITED_ABORT 0xf3 #define PQI_DATA_IN_OUT_ABORTED 0xf4 #define PQI_DATA_IN_OUT_TIMEOUT 0xf5 /* ---- additional CDB bytes usage field codes ---- */ #define SOP_ADDITIONAL_CDB_BYTES_0 0 /* 16-byte CDB */ #define SOP_ADDITIONAL_CDB_BYTES_4 1 /* 20-byte CDB */ #define SOP_ADDITIONAL_CDB_BYTES_8 2 /* 24-byte CDB */ #define SOP_ADDITIONAL_CDB_BYTES_12 3 /* 28-byte CDB */ #define SOP_ADDITIONAL_CDB_BYTES_16 4 /* 32-byte CDB */ /* ---- These values are defined by the PQI spec ---- */ #define PQI_MAX_NUM_ELEMENTS_ADMIN_QUEUE 255 #define PQI_MAX_NUM_ELEMENTS_OPERATIONAL_QUEUE 65535 #define PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT 64 #define PQI_QUEUE_ELEMENT_LENGTH_ALIGNMENT 16 #define PQI_ADMIN_INDEX_ALIGNMENT 64 #define PQI_OPERATIONAL_INDEX_ALIGNMENT 4 /* ---- These values are based on our implementation ---- */ #define PQI_ADMIN_IQ_NUM_ELEMENTS 8 #define PQI_ADMIN_OQ_NUM_ELEMENTS 20 #define PQI_ADMIN_IQ_ELEMENT_LENGTH 64 #define PQI_ADMIN_OQ_ELEMENT_LENGTH 64 #define PQI_OPERATIONAL_IQ_ELEMENT_LENGTH 128 #define PQI_OPERATIONAL_OQ_ELEMENT_LENGTH 16 #define PQI_NUM_EVENT_QUEUE_ELEMENTS 32 #define PQI_EVENT_OQ_ELEMENT_LENGTH sizeof (struct pqi_event_response) #define PQI_MAX_EMBEDDED_SG_DESCRIPTORS 4 #define PQI_EXTRA_SGL_MEMORY (12 * sizeof (pqi_sg_entry_t)) typedef uint32_t pqi_index_t; /* * The purpose of this structure is to obtain proper alignment of objects in * an admin queue pair. * NOTE: Make sure to not move this structure to within the * #pragma pack(1) * directives below. Those directives will override the __aligned directives * which in turn will cause the driver to fail. */ typedef struct pqi_admin_queues_aligned { __aligned(PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT) uint8_t iq_element_array[PQI_ADMIN_IQ_NUM_ELEMENTS] [PQI_ADMIN_IQ_ELEMENT_LENGTH]; __aligned(PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT) uint8_t oq_element_array[PQI_ADMIN_OQ_NUM_ELEMENTS] [PQI_ADMIN_OQ_ELEMENT_LENGTH]; __aligned(PQI_ADMIN_INDEX_ALIGNMENT) pqi_index_t iq_ci; __aligned(PQI_ADMIN_INDEX_ALIGNMENT) pqi_index_t oq_pi; } pqi_admin_queues_aligned_t; /* * NOTE: * From here to the end of the file #pragma pack(1) is set to maintain * the structure alignment required by the hardware. Don't change that. */ #pragma pack(1) /* ---- This structure is defined by the PQI specification. ---- */ struct pqi_device_registers { uint64_t signature; uint64_t function_and_status_code; uint8_t max_admin_iq_elements; uint8_t max_admin_oq_elements; uint8_t admin_iq_element_length; /* in 16-byte units */ uint8_t admin_oq_element_length; /* in 16-byte units */ uint16_t max_reset_timeout; /* in 100-millisecond units */ uint8_t reserved1[2]; uint32_t legacy_intx_status; uint32_t legacy_intx_mask_set; uint32_t legacy_intx_mask_clear; uint8_t reserved2[28]; uint32_t device_status; uint8_t reserved3[4]; uint64_t admin_iq_pi_offset; uint64_t admin_oq_ci_offset; uint64_t admin_iq_element_array_addr; uint64_t admin_oq_element_array_addr; uint64_t admin_iq_ci_addr; uint64_t admin_oq_pi_addr; /* * byte 0 -- iq number of elements * byte 1 -- oq number of elements * byte 2 -- interrupt message number (IMN) * byte 3 -- 3 upper bits for IMN and MSIX disable bit */ uint32_t admin_queue_params; uint8_t reserved4[4]; uint32_t device_error; uint8_t reserved5[4]; uint64_t error_details; uint32_t device_reset; uint32_t power_action; uint8_t reserved6[104]; }; /* * controller registers * * These are defined by the Microsemi implementation. * * Some registers (those named sis_*) are only used when in * legacy SIS mode before we transition the controller into * PQI mode. There are a number of other SIS mode registers, * but we don't use them, so only the SIS registers that we * care about are defined here. The offsets mentioned in the * comments are the offsets from the PCIe BAR 0. */ typedef struct pqi_ctrl_registers { uint8_t reserved[0x20]; uint32_t sis_host_to_ctrl_doorbell; /* 20h */ uint8_t reserved1[0x34 - (0x20 + sizeof (uint32_t))]; uint32_t sis_interrupt_mask; /* 34h */ uint8_t reserved2[0x9c - (0x34 + sizeof (uint32_t))]; uint32_t sis_ctrl_to_host_doorbell; /* 9Ch */ /* uint8_t reserved3[0xa0 - (0x9c + sizeof (uint32_t))]; */ uint32_t sis_ctrl_to_host_doorbell_clear; /* A0h */ uint8_t reserved4[0xb0 - (0xa0 + sizeof (uint32_t))]; uint32_t sis_driver_scratch; /* B0h */ uint8_t reserved5[0xbc - (0xb0 + sizeof (uint32_t))]; uint32_t sis_firmware_status; /* BCh */ uint8_t reserved6[0x1000 - (0xbc + sizeof (uint32_t))]; uint32_t sis_mailbox[8]; /* 1000h */ uint8_t reserved7[0x4000 - (0x1000 + (sizeof (uint32_t) * 8))]; /* * The PQI spec states that the PQI registers should be at * offset 0 from the PCIe BAR 0. However, we can't map * them at offset 0 because that would break compatibility * with the SIS registers. So we map them at offset 4000h. */ struct pqi_device_registers pqi_registers; /* 4000h */ } pqi_ctrl_regs_t; #define PQI_DEVICE_REGISTERS_OFFSET 0x4000 typedef struct pqi_iu_header { uint8_t iu_type; uint8_t reserved; /* in bytes - does not include the length of this header */ uint16_t iu_length; /* specifies the OQ where the response IU is to be delivered */ uint16_t iu_id; uint8_t work_area[2]; /* reserved for driver use */ } pqi_iu_header_t; typedef struct pqi_sg_entry { uint64_t sg_addr; uint32_t sg_len; uint32_t sg_flags; } pqi_sg_entry_t; typedef struct pqi_raid_path_request { pqi_iu_header_t header; uint16_t rp_id; uint16_t rp_nexus_id; uint32_t rp_data_len; uint8_t rp_lun[8]; uint16_t protocol_specific; uint8_t rp_data_dir : 2; uint8_t rp_partial : 1; uint8_t reserved1 : 4; uint8_t rp_fence : 1; uint16_t rp_error_index; uint8_t reserved2; uint8_t rp_task_attr : 3; uint8_t rp_pri : 4; uint8_t reserved3 : 1; uint8_t reserved4 : 2; uint8_t rp_additional_cdb : 3; uint8_t reserved5 : 3; uint8_t rp_cdb[32]; pqi_sg_entry_t rp_sglist[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; } pqi_raid_path_request_t; typedef struct pqi_aio_path_request { pqi_iu_header_t header; uint16_t request_id; uint8_t reserved1[2]; uint32_t nexus_id; uint32_t buffer_length; uint8_t data_direction : 2; uint8_t partial : 1; uint8_t memory_type : 1; uint8_t fence : 1; uint8_t encryption_enable : 1; uint8_t reserved2 : 2; uint8_t task_attribute : 3; uint8_t command_priority : 4; uint8_t reserved3 : 1; uint16_t data_encryption_key_index; uint32_t encrypt_tweak_lower; uint32_t encrypt_tweak_upper; uint8_t cdb[16]; uint16_t error_index; uint8_t num_sg_descriptors; uint8_t cdb_length; uint8_t lun_number[8]; uint8_t reserved4[4]; pqi_sg_entry_t ap_sglist[PQI_MAX_EMBEDDED_SG_DESCRIPTORS]; } pqi_aio_path_request_t; typedef struct pqi_io_response { pqi_iu_header_t header; uint16_t request_id; uint16_t error_index; uint8_t reserved2[4]; } pqi_io_response_t; typedef struct pqi_raid_error_info { uint8_t data_in_result; uint8_t data_out_result; uint8_t reserved[3]; uint8_t status; uint16_t status_qualifier; uint16_t sense_data_length; uint16_t response_data_length; uint32_t data_in_transferred; uint32_t data_out_transferred; uint8_t data[256]; } *pqi_raid_error_info_t; #define PQI_GENERAL_ADMIN_FUNCTION_REPORT_DEVICE_CAPABILITY 0x0 #define PQI_GENERAL_ADMIN_FUNCTION_CREATE_IQ 0x10 #define PQI_GENERAL_ADMIN_FUNCTION_CREATE_OQ 0x11 #define PQI_GENERAL_ADMIN_FUNCTION_DELETE_IQ 0x12 #define PQI_GENERAL_ADMIN_FUNCTION_DELETE_OQ 0x13 #define PQI_GENERAL_ADMIN_FUNCTION_CHANGE_IQ_PROPERTY 0x14 #define PQI_GENERAL_ADMIN_STATUS_SUCCESS 0x0 #define PQI_GENERAL_ADMIN_IU_LENGTH 0x3c #define PQI_PROTOCOL_SOP 0x0 #define PQI_IQ_PROPERTY_IS_AIO_QUEUE 0x1 typedef struct pqi_iu_layer_descriptor { uint8_t inbound_spanning_supported : 1; uint8_t reserved : 7; uint8_t reserved1[5]; uint16_t max_inbound_iu_length; uint8_t outbound_spanning_supported : 1; uint8_t reserved2 : 7; uint8_t reserved3[5]; uint16_t max_outbound_iu_length; } pqi_iu_layer_descriptor_t; typedef struct pqi_device_capability { uint16_t data_length; uint8_t reserved[6]; uint8_t iq_arbitration_priority_support_bitmask; uint8_t maximum_aw_a; uint8_t maximum_aw_b; uint8_t maximum_aw_c; uint8_t max_arbitration_burst : 3; uint8_t reserved1 : 4; uint8_t iqa : 1; uint8_t reserved2[2]; uint8_t iq_freeze : 1; uint8_t reserved3 : 7; uint16_t max_inbound_queues; uint16_t max_elements_per_iq; uint8_t reserved4[4]; uint16_t max_iq_element_length; uint16_t min_iq_element_length; uint8_t reserved5[2]; uint16_t max_outbound_queues; uint16_t max_elements_per_oq; uint16_t intr_coalescing_time_granularity; uint16_t max_oq_element_length; uint16_t min_oq_element_length; uint8_t reserved6[24]; pqi_iu_layer_descriptor_t iu_layer_descriptors[32]; } pqi_device_capability_t; typedef struct pqi_general_management_request { pqi_iu_header_t header; uint16_t request_id; union { struct { uint8_t reserved[2]; uint32_t buffer_length; pqi_sg_entry_t sg_descriptors[3]; } report_event_configuration; struct { uint16_t global_event_oq_id; uint32_t buffer_length; pqi_sg_entry_t sg_descriptors[3]; } set_event_configuration; } data; } pqi_general_mgmt_rqst_t; #define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0" typedef struct pqi_config_table { uint8_t signature[8]; /* "CFGTABLE" */ /* offset in bytes from the base address of this table to the */ /* first section */ uint32_t first_section_offset; } pqi_config_table_t; typedef struct pqi_config_table_section_header { /* as defined by the PQI_CONFIG_TABLE_SECTION_* manifest */ /* constants above */ uint16_t section_id; /* offset in bytes from base address of the table of the */ /* next section or 0 if last entry */ uint16_t next_section_offset; } pqi_config_table_section_header_t; struct pqi_config_table_general_info { pqi_config_table_section_header_t header; /* size of this section in bytes including the section header */ uint32_t section_length; /* max. outstanding commands supported by the controller */ uint32_t max_outstanding_requests; /* max. transfer size of a single command */ uint32_t max_sg_size; /* max. number of scatter-gather entries supported in a single cmd */ uint32_t max_sg_per_request; }; typedef struct pqi_config_table_heartbeat { pqi_config_table_section_header_t header; uint32_t heartbeat_counter; } pqi_config_table_heartbeat_t; typedef struct pqi_general_admin_request { pqi_iu_header_t header; uint16_t request_id; uint8_t function_code; union { struct { uint8_t reserved[33]; uint32_t buffer_length; pqi_sg_entry_t sg_descriptor; } report_device_capability; struct { uint8_t reserved; uint16_t queue_id; uint8_t reserved1[2]; uint64_t element_array_addr; uint64_t ci_addr; uint16_t num_elements; uint16_t element_length; uint8_t queue_protocol; uint8_t reserved2[23]; uint32_t vendor_specific; } create_operational_iq; struct { uint8_t reserved; uint16_t queue_id; uint8_t reserved1[2]; uint64_t element_array_addr; uint64_t pi_addr; uint16_t num_elements; uint16_t element_length; uint8_t queue_protocol; uint8_t reserved2[3]; uint16_t int_msg_num; uint16_t coalescing_count; uint32_t min_coalescing_time; uint32_t max_coalescing_time; uint8_t reserved3[8]; uint32_t vendor_specific; } create_operational_oq; struct { uint8_t reserved; uint16_t queue_id; uint8_t reserved1[50]; } delete_operational_queue; struct { uint8_t reserved; uint16_t queue_id; uint8_t reserved1[46]; uint32_t vendor_specific; } change_operational_iq_properties; } data; } pqi_general_admin_request_t; #define PQI_RESPONSE_IU_GENERAL_MANAGEMENT 0x81 #define PQI_RESPONSE_IU_TASK_MANAGEMENT 0x93 #define PQI_RESPONSE_IU_GENERAL_ADMIN 0xe0 #define PQI_RESPONSE_IU_RAID_PATH_IO_SUCCESS 0xf0 #define PQI_RESPONSE_IU_AIO_PATH_IO_SUCCESS 0xf1 #define PQI_RESPONSE_IU_RAID_PATH_IO_ERROR 0xf2 #define PQI_RESPONSE_IU_AIO_PATH_IO_ERROR 0xf3 #define PQI_RESPONSE_IU_AIO_PATH_DISABLED 0xf4 #define PQI_RESPONSE_IU_VENDOR_EVENT 0xf5 typedef struct pqi_general_admin_response { pqi_iu_header_t header; uint16_t request_id; uint8_t function_code; uint8_t status; union { struct { uint8_t status_descriptor[4]; uint64_t iq_pi_offset; uint8_t reserved[40]; } create_operational_iq; struct { uint8_t status_descriptor[4]; uint64_t oq_ci_offset; uint8_t reserved[40]; } create_operational_oq; } data; } pqi_general_admin_response_t; typedef struct pqi_task_management_rqst { pqi_iu_header_t header; uint16_t request_id; uint16_t nexus_id; uint8_t reserved[4]; uint8_t lun_number[8]; uint16_t protocol_specific; uint16_t outbound_queue_id_to_manage; uint16_t request_id_to_manage; uint8_t task_management_function; uint8_t reserved2 : 7; uint8_t fence : 1; } pqi_task_management_rqst_t; /* ---- Support event types ---- */ #define PQI_EVENT_TYPE_HOTPLUG 0x1 #define PQI_EVENT_TYPE_HARDWARE 0x2 #define PQI_EVENT_TYPE_PHYSICAL_DEVICE 0x4 #define PQI_EVENT_TYPE_LOGICAL_DEVICE 0x5 #define PQI_EVENT_TYPE_AIO_STATE_CHANGE 0xfd #define PQI_EVENT_TYPE_AIO_CONFIG_CHANGE 0xfe #define PQI_EVENT_TYPE_HEARTBEAT 0xff typedef struct pqi_event_response { pqi_iu_header_t header; uint8_t event_type; uint8_t reserved2 : 7; uint8_t request_acknowlege : 1; uint16_t event_id; uint32_t additional_event_id; uint8_t data[16]; } pqi_event_response_t; typedef struct pqi_event_acknowledge_request { pqi_iu_header_t header; uint8_t event_type; uint8_t reserved2; uint16_t event_id; uint32_t additional_event_id; } pqi_event_acknowledge_request_t; typedef struct pqi_event_descriptor { uint8_t event_type; uint8_t reserved; uint16_t oq_id; } pqi_event_descriptor_t; typedef struct pqi_event_config { uint8_t reserved[2]; uint8_t num_event_descriptors; uint8_t reserved1; pqi_event_descriptor_t descriptors[1]; } pqi_event_config_t; typedef struct bmic_identify_controller { uint8_t configured_logical_drive_count; uint32_t configuration_signature; uint8_t firmware_version[4]; uint8_t reserved[145]; uint16_t extended_logical_unit_count; uint8_t reserved1[34]; uint16_t firmware_build_number; uint8_t reserved2[100]; uint8_t controller_mode; uint8_t reserved3[32]; } bmic_identify_controller_t; #define CISS_GET_LEVEL_2_BUS(lunid) ((lunid)[7] & 0x3f) #define CISS_GET_LEVEL_2_TARGET(lunid) ((lunid)[6]) #define CISS_GET_DRIVE_NUMBER(lunid) \ (((CISS_GET_LEVEL_2_BUS((lunid)) - 1) << 8) + \ CISS_GET_LEVEL_2_TARGET((lunid))) typedef struct bmic_identify_physical_device { uint8_t scsi_bus; /* SCSI Bus number on controller */ uint8_t scsi_id; /* SCSI ID on this bus */ uint16_t block_size; /* sector size in bytes */ uint32_t total_blocks; /* number for sectors on drive */ uint32_t reserved_blocks; /* controller reserved (RIS) */ uint8_t model[40]; /* Physical Drive Model */ uint8_t serial_number[40]; /* Drive Serial Number */ uint8_t firmware_revision[8]; /* drive firmware revision */ uint8_t scsi_inquiry_bits; /* inquiry byte 7 bits */ uint8_t compaq_drive_stamp; /* 0 means drive not stamped */ uint8_t last_failure_reason; uint8_t flags; uint8_t more_flags; uint8_t scsi_lun; /* SCSI LUN for phys drive */ uint8_t yet_more_flags; uint8_t even_more_flags; uint32_t spi_speed_rules; uint8_t phys_connector[2]; /* connector number on controller */ uint8_t phys_box_on_bus; /* phys enclosure this drive resides */ uint8_t phys_bay_in_box; /* phys drv bay this drive resides */ uint32_t rpm; /* drive rotational speed in RPM */ uint8_t device_type; /* type of drive */ uint8_t sata_version; /* only valid when device_type = */ /* BMIC_DEVICE_TYPE_SATA */ uint64_t big_total_block_count; uint64_t ris_starting_lba; uint32_t ris_size; uint8_t wwid[20]; uint8_t controller_phy_map[32]; uint16_t phy_count; uint8_t phy_connected_dev_type[256]; uint8_t phy_to_drive_bay_num[256]; uint16_t phy_to_attached_dev_index[256]; uint8_t box_index; uint8_t reserved; uint16_t extra_physical_drive_flags; uint8_t negotiated_link_rate[256]; uint8_t phy_to_phy_map[256]; uint8_t redundant_path_present_map; uint8_t redundant_path_failure_map; uint8_t active_path_number; uint16_t alternate_paths_phys_connector[8]; uint8_t alternate_paths_phys_box_on_port[8]; uint8_t multi_lun_device_lun_count; uint8_t minimum_good_fw_revision[8]; uint8_t unique_inquiry_bytes[20]; uint8_t current_temperature_degrees; uint8_t temperature_threshold_degrees; uint8_t max_temperature_degrees; uint8_t logical_blocks_per_phys_block_exp; uint16_t current_queue_depth_limit; uint8_t switch_name[10]; uint16_t switch_port; uint8_t alternate_paths_switch_name[40]; uint8_t alternate_paths_switch_port[8]; uint16_t power_on_hours; uint16_t percent_endurance_used; uint8_t drive_authentication; uint8_t smart_carrier_authentication; uint8_t smart_carrier_app_fw_version; uint8_t smart_carrier_bootloader_fw_version; uint8_t sanitize_flags; uint8_t encryption_key_flags; uint8_t encryption_key_name[64]; uint32_t misc_drive_flags; uint16_t dek_index; uint16_t hba_drive_encryption_flags; uint16_t max_overwrite_time; uint16_t max_block_erase_time; uint16_t max_crypto_erase_time; uint8_t connector_info[5]; uint8_t connector_name[8][8]; uint8_t page_83_identifier[16]; uint8_t maximum_link_rate[256]; uint8_t negotiated_physical_link_rate[256]; uint8_t box_connector_name[8]; uint8_t padding_to_multiple_of_512[9]; } bmic_identify_physical_device_t; typedef struct bmic_host_wellness_driver_version { uint8_t start_tag[4]; uint8_t drv_tag[2]; uint16_t driver_version_length; char driver_version[32]; uint8_t end_tag[2]; } bmic_host_wellness_driver_version_t; typedef struct bmic_host_wellness_time { uint8_t start_tag[4]; uint8_t time_tag[2]; uint16_t time_length; uint8_t time[8]; uint8_t dont_write_tag[2]; uint8_t end_tag[2]; } bmic_host_wellness_time_t; #define PQI_MAX_EVENT_DESCRIPTORS 255 typedef struct report_lun_header { uint32_t list_length; uint8_t extended_response; uint8_t reserved[3]; } report_lun_header_t; typedef struct report_log_lun_extended_entry { uint8_t lunid[8]; uint8_t volume_id[16]; } report_log_lun_extended_entry_t; typedef struct report_log_lun_extended { report_lun_header_t header; report_log_lun_extended_entry_t lun_entries[1]; } report_log_lun_extended_t; typedef struct report_phys_lun_extended_entry { uint8_t lunid[8]; uint64_t wwid; uint8_t device_type; uint8_t device_flags; uint8_t lun_count; /* number of LUNs in a multi-LUN device */ uint8_t redundant_paths; uint32_t aio_handle; } report_phys_lun_extended_entry_t; /* ---- Zoned Block Device ---- */ #define TYPE_ZBC 0x14 /* for device_flags field of struct report_phys_lun_extended_entry */ #define REPORT_PHYS_LUN_DEV_FLAG_AIO_ENABLED 0x8 typedef struct report_phys_lun_extended { report_lun_header_t header; report_phys_lun_extended_entry_t lun_entries[1]; } report_phys_lun_extended_t; #pragma pack() #ifdef __cplusplus } #endif #endif /* _SMARTPQI_HW_H */