1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2018 Nexenta Systems, Inc.
  14  */
  15 
  16 #ifndef _SMARTPQI_HW_H
  17 #define _SMARTPQI_HW_H
  18 
  19 #ifdef __cplusplus
  20 extern "C" {
  21 #endif
  22 
  23 #include <sys/types.h>
  24 #include <sys/ccompile.h>
  25 
  26 /* ---- for submission of legacy SIS commands ---- */
  27 #define SIS_REENABLE_SIS_MODE                   0x1
  28 #define SIS_ENABLE_MSIX                         0x40
  29 #define SIS_ENABLE_INTX                         0x80
  30 #define SIS_SOFT_RESET                          0x100
  31 #define SIS_TRIGGER_SHUTDOWN                    0x800000
  32 #define SIS_CMD_READY                           0x200
  33 #define SIS_CMD_COMPLETE                        0x1000
  34 #define SIS_CLEAR_CTRL_TO_HOST_DOORBELL         0x1000
  35 #define SIS_CMD_STATUS_SUCCESS                  0x1
  36 #define SIS_CMD_COMPLETE_TIMEOUT_SECS           30
  37 #define SIS_CMD_COMPLETE_POLL_INTERVAL_MSECS    10
  38 
  39 /* ---- SOP data direction flags ---- */
  40 #define SOP_NO_DIRECTION_FLAG   0
  41 #define SOP_WRITE_FLAG          1       /* host writes data to Data-Out */
  42                                         /* buffer */
  43 #define SOP_READ_FLAG           2       /* host receives data from Data-In */
  44                                         /* buffer */
  45 #define SOP_BIDIRECTIONAL       3       /* data is transferred from the */
  46                                         /* Data-Out buffer and data is */
  47                                         /* transferred to the Data-In buffer */
  48 
  49 #define SOP_TASK_ATTRIBUTE_SIMPLE               0
  50 #define SOP_TASK_ATTRIBUTE_HEAD_OF_QUEUE        1
  51 #define SOP_TASK_ATTRIBUTE_ORDERED              2
  52 #define SOP_TASK_ATTRIBUTE_ACA                  4
  53 
  54 #define SOP_TMF_COMPLETE                0x0
  55 #define SOP_TMF_FUNCTION_SUCCEEDED      0x8
  56 
  57 #define SOP_TASK_MANAGEMENT_LUN_RESET   0x08
  58 
  59 /* ---- CISS commands ---- */
  60 #define CISS_READ                               0xc0
  61 #define CISS_REPORT_LOG                         0xc2
  62 #define CISS_REPORT_PHYS                        0xc3
  63 #define CISS_GET_RAID_MAP                       0xc8
  64 
  65 /* constants for CISS_REPORT_LOG/CISS_REPORT_PHYS commands */
  66 #define CISS_REPORT_LOG_EXTENDED                0x1
  67 #define CISS_REPORT_PHYS_EXTENDED               0x2
  68 
  69 /* BMIC commands */
  70 #define BMIC_IDENTIFY_CONTROLLER                0x11
  71 #define BMIC_IDENTIFY_PHYSICAL_DEVICE           0x15
  72 #define BMIC_READ                               0x26
  73 #define BMIC_WRITE                              0x27
  74 #define BMIC_SENSE_CONTROLLER_PARAMETERS        0x64
  75 #define BMIC_SENSE_SUBSYSTEM_INFORMATION        0x66
  76 #define BMIC_WRITE_HOST_WELLNESS                0xa5
  77 #define BMIC_CACHE_FLUSH                        0xc2
  78 
  79 #define PQI_DATA_IN_OUT_GOOD                                    0x0
  80 #define PQI_DATA_IN_OUT_UNDERFLOW                               0x1
  81 #define PQI_DATA_IN_OUT_BUFFER_ERROR                            0x40
  82 #define PQI_DATA_IN_OUT_BUFFER_OVERFLOW                         0x41
  83 #define PQI_DATA_IN_OUT_BUFFER_OVERFLOW_DESCRIPTOR_AREA         0x42
  84 #define PQI_DATA_IN_OUT_BUFFER_OVERFLOW_BRIDGE                  0x43
  85 #define PQI_DATA_IN_OUT_PCIE_FABRIC_ERROR                       0x60
  86 #define PQI_DATA_IN_OUT_PCIE_COMPLETION_TIMEOUT                 0x61
  87 #define PQI_DATA_IN_OUT_PCIE_COMPLETER_ABORT_RECEIVED           0x62
  88 #define PQI_DATA_IN_OUT_PCIE_UNSUPPORTED_REQUEST_RECEIVED       0x63
  89 #define PQI_DATA_IN_OUT_PCIE_ECRC_CHECK_FAILED                  0x64
  90 #define PQI_DATA_IN_OUT_PCIE_UNSUPPORTED_REQUEST                0x65
  91 #define PQI_DATA_IN_OUT_PCIE_ACS_VIOLATION                      0x66
  92 #define PQI_DATA_IN_OUT_PCIE_TLP_PREFIX_BLOCKED                 0x67
  93 #define PQI_DATA_IN_OUT_PCIE_POISONED_MEMORY_READ               0x6F
  94 #define PQI_DATA_IN_OUT_ERROR                                   0xf0
  95 #define PQI_DATA_IN_OUT_PROTOCOL_ERROR                          0xf1
  96 #define PQI_DATA_IN_OUT_HARDWARE_ERROR                          0xf2
  97 #define PQI_DATA_IN_OUT_UNSOLICITED_ABORT                       0xf3
  98 #define PQI_DATA_IN_OUT_ABORTED                                 0xf4
  99 #define PQI_DATA_IN_OUT_TIMEOUT                                 0xf5
 100 
 101 /* ---- additional CDB bytes usage field codes ---- */
 102 #define SOP_ADDITIONAL_CDB_BYTES_0      0       /* 16-byte CDB */
 103 #define SOP_ADDITIONAL_CDB_BYTES_4      1       /* 20-byte CDB */
 104 #define SOP_ADDITIONAL_CDB_BYTES_8      2       /* 24-byte CDB */
 105 #define SOP_ADDITIONAL_CDB_BYTES_12     3       /* 28-byte CDB */
 106 #define SOP_ADDITIONAL_CDB_BYTES_16     4       /* 32-byte CDB */
 107 
 108 /* ---- These values are defined by the PQI spec ---- */
 109 #define PQI_MAX_NUM_ELEMENTS_ADMIN_QUEUE                255
 110 #define PQI_MAX_NUM_ELEMENTS_OPERATIONAL_QUEUE          65535
 111 #define PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT               64
 112 #define PQI_QUEUE_ELEMENT_LENGTH_ALIGNMENT              16
 113 #define PQI_ADMIN_INDEX_ALIGNMENT                       64
 114 #define PQI_OPERATIONAL_INDEX_ALIGNMENT                 4
 115 
 116 /* ---- These values are based on our implementation ---- */
 117 #define PQI_ADMIN_IQ_NUM_ELEMENTS                       8
 118 #define PQI_ADMIN_OQ_NUM_ELEMENTS                       20
 119 #define PQI_ADMIN_IQ_ELEMENT_LENGTH                     64
 120 #define PQI_ADMIN_OQ_ELEMENT_LENGTH                     64
 121 
 122 #define PQI_OPERATIONAL_IQ_ELEMENT_LENGTH               128
 123 #define PQI_OPERATIONAL_OQ_ELEMENT_LENGTH               16
 124 
 125 #define PQI_NUM_EVENT_QUEUE_ELEMENTS                    32
 126 #define PQI_EVENT_OQ_ELEMENT_LENGTH     sizeof (struct pqi_event_response)
 127 
 128 #define PQI_MAX_EMBEDDED_SG_DESCRIPTORS                 4
 129 
 130 #define PQI_EXTRA_SGL_MEMORY    (12 * sizeof (pqi_sg_entry_t))
 131 
 132 typedef uint32_t        pqi_index_t;
 133 
 134 /*
 135  * The purpose of this structure is to obtain proper alignment of objects in
 136  * an admin queue pair.
 137  * NOTE: Make sure to not move this structure to within the
 138  *    #pragma pack(1)
 139  * directives below. Those directives will override the __aligned directives
 140  * which in turn will cause the driver to fail.
 141  */
 142 typedef struct pqi_admin_queues_aligned {
 143         __aligned(PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT)
 144         uint8_t iq_element_array[PQI_ADMIN_IQ_NUM_ELEMENTS]
 145             [PQI_ADMIN_IQ_ELEMENT_LENGTH];
 146         __aligned(PQI_QUEUE_ELEMENT_ARRAY_ALIGNMENT)
 147         uint8_t oq_element_array[PQI_ADMIN_OQ_NUM_ELEMENTS]
 148             [PQI_ADMIN_OQ_ELEMENT_LENGTH];
 149         __aligned(PQI_ADMIN_INDEX_ALIGNMENT) pqi_index_t iq_ci;
 150         __aligned(PQI_ADMIN_INDEX_ALIGNMENT) pqi_index_t oq_pi;
 151 } pqi_admin_queues_aligned_t;
 152 
 153 /*
 154  * NOTE:
 155  * From here to the end of the file #pragma pack(1) is set to maintain
 156  * the structure alignment required by the hardware. Don't change that.
 157  */
 158 #pragma pack(1)
 159 /* ---- This structure is defined by the PQI specification. ---- */
 160 struct pqi_device_registers {
 161         uint64_t        signature;
 162         uint64_t        function_and_status_code;
 163         uint8_t         max_admin_iq_elements;
 164         uint8_t         max_admin_oq_elements;
 165         uint8_t         admin_iq_element_length; /* in 16-byte units */
 166         uint8_t         admin_oq_element_length; /* in 16-byte units */
 167         uint16_t        max_reset_timeout;      /* in 100-millisecond units */
 168         uint8_t         reserved1[2];
 169         uint32_t        legacy_intx_status;
 170         uint32_t        legacy_intx_mask_set;
 171         uint32_t        legacy_intx_mask_clear;
 172         uint8_t         reserved2[28];
 173         uint32_t        device_status;
 174         uint8_t         reserved3[4];
 175         uint64_t        admin_iq_pi_offset;
 176         uint64_t        admin_oq_ci_offset;
 177         uint64_t        admin_iq_element_array_addr;
 178         uint64_t        admin_oq_element_array_addr;
 179         uint64_t        admin_iq_ci_addr;
 180         uint64_t        admin_oq_pi_addr;
 181         /*
 182          * byte 0 -- iq number of elements
 183          * byte 1 -- oq number of elements
 184          * byte 2 -- interrupt message number (IMN)
 185          * byte 3 -- 3 upper bits for IMN and MSIX disable bit
 186          */
 187         uint32_t        admin_queue_params;
 188         uint8_t         reserved4[4];
 189         uint32_t        device_error;
 190         uint8_t         reserved5[4];
 191         uint64_t        error_details;
 192         uint32_t        device_reset;
 193         uint32_t        power_action;
 194         uint8_t         reserved6[104];
 195 };
 196 
 197 /*
 198  * controller registers
 199  *
 200  * These are defined by the Microsemi implementation.
 201  *
 202  * Some registers (those named sis_*) are only used when in
 203  * legacy SIS mode before we transition the controller into
 204  * PQI mode.  There are a number of other SIS mode registers,
 205  * but we don't use them, so only the SIS registers that we
 206  * care about are defined here.  The offsets mentioned in the
 207  * comments are the offsets from the PCIe BAR 0.
 208  */
 209 typedef struct pqi_ctrl_registers {
 210         uint8_t         reserved[0x20];
 211         uint32_t        sis_host_to_ctrl_doorbell;              /* 20h */
 212         uint8_t         reserved1[0x34 - (0x20 + sizeof (uint32_t))];
 213         uint32_t        sis_interrupt_mask;                     /* 34h */
 214         uint8_t         reserved2[0x9c - (0x34 + sizeof (uint32_t))];
 215         uint32_t        sis_ctrl_to_host_doorbell;              /* 9Ch */
 216         /* uint8_t      reserved3[0xa0 - (0x9c + sizeof (uint32_t))]; */
 217         uint32_t        sis_ctrl_to_host_doorbell_clear;        /* A0h */
 218         uint8_t         reserved4[0xb0 - (0xa0 + sizeof (uint32_t))];
 219         uint32_t        sis_driver_scratch;                     /* B0h */
 220         uint8_t         reserved5[0xbc - (0xb0 + sizeof (uint32_t))];
 221         uint32_t        sis_firmware_status;                    /* BCh */
 222         uint8_t         reserved6[0x1000 - (0xbc + sizeof (uint32_t))];
 223         uint32_t        sis_mailbox[8];                         /* 1000h */
 224         uint8_t         reserved7[0x4000 - (0x1000 + (sizeof (uint32_t) * 8))];
 225 
 226         /*
 227          * The PQI spec states that the PQI registers should be at
 228          * offset 0 from the PCIe BAR 0.  However, we can't map
 229          * them at offset 0 because that would break compatibility
 230          * with the SIS registers.  So we map them at offset 4000h.
 231          */
 232         struct pqi_device_registers pqi_registers;              /* 4000h */
 233 } pqi_ctrl_regs_t;
 234 #define PQI_DEVICE_REGISTERS_OFFSET     0x4000
 235 
 236 typedef struct pqi_iu_header {
 237         uint8_t         iu_type;
 238         uint8_t         reserved;
 239 
 240         /* in bytes - does not include the length of this header */
 241         uint16_t        iu_length;
 242 
 243         /* specifies the OQ where the response IU is to be delivered */
 244         uint16_t        iu_id;
 245 
 246         uint8_t         work_area[2];   /* reserved for driver use */
 247 } pqi_iu_header_t;
 248 
 249 typedef struct pqi_sg_entry {
 250         uint64_t  sg_addr;
 251         uint32_t  sg_len;
 252         uint32_t  sg_flags;
 253 } pqi_sg_entry_t;
 254 
 255 typedef struct pqi_raid_path_request {
 256         pqi_iu_header_t header;
 257         uint16_t        rp_id;
 258         uint16_t        rp_nexus_id;
 259         uint32_t        rp_data_len;
 260         uint8_t         rp_lun[8];
 261         uint16_t        protocol_specific;
 262         uint8_t         rp_data_dir : 2;
 263         uint8_t         rp_partial : 1;
 264         uint8_t         reserved1 : 4;
 265         uint8_t         rp_fence : 1;
 266         uint16_t        rp_error_index;
 267         uint8_t         reserved2;
 268         uint8_t         rp_task_attr : 3;
 269         uint8_t         rp_pri : 4;
 270         uint8_t         reserved3 : 1;
 271         uint8_t         reserved4 : 2;
 272         uint8_t         rp_additional_cdb : 3;
 273         uint8_t         reserved5 : 3;
 274         uint8_t         rp_cdb[32];
 275         pqi_sg_entry_t  rp_sglist[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
 276 } pqi_raid_path_request_t;
 277 
 278 typedef struct pqi_aio_path_request {
 279         pqi_iu_header_t header;
 280         uint16_t        request_id;
 281         uint8_t         reserved1[2];
 282         uint32_t        nexus_id;
 283         uint32_t        buffer_length;
 284         uint8_t         data_direction : 2;
 285         uint8_t         partial : 1;
 286         uint8_t         memory_type : 1;
 287         uint8_t         fence : 1;
 288         uint8_t         encryption_enable : 1;
 289         uint8_t         reserved2 : 2;
 290         uint8_t         task_attribute : 3;
 291         uint8_t         command_priority : 4;
 292         uint8_t         reserved3 : 1;
 293         uint16_t        data_encryption_key_index;
 294         uint32_t        encrypt_tweak_lower;
 295         uint32_t        encrypt_tweak_upper;
 296         uint8_t         cdb[16];
 297         uint16_t        error_index;
 298         uint8_t         num_sg_descriptors;
 299         uint8_t         cdb_length;
 300         uint8_t         lun_number[8];
 301         uint8_t         reserved4[4];
 302         pqi_sg_entry_t  ap_sglist[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
 303 } pqi_aio_path_request_t;
 304 
 305 typedef struct pqi_io_response {
 306         pqi_iu_header_t header;
 307         uint16_t        request_id;
 308         uint16_t        error_index;
 309         uint8_t         reserved2[4];
 310 } pqi_io_response_t;
 311 
 312 typedef struct pqi_raid_error_info {
 313         uint8_t         data_in_result;
 314         uint8_t         data_out_result;
 315         uint8_t         reserved[3];
 316         uint8_t         status;
 317         uint16_t        status_qualifier;
 318         uint16_t        sense_data_length;
 319         uint16_t        response_data_length;
 320         uint32_t        data_in_transferred;
 321         uint32_t        data_out_transferred;
 322         uint8_t         data[256];
 323 } *pqi_raid_error_info_t;
 324 
 325 #define PQI_GENERAL_ADMIN_FUNCTION_REPORT_DEVICE_CAPABILITY     0x0
 326 #define PQI_GENERAL_ADMIN_FUNCTION_CREATE_IQ                    0x10
 327 #define PQI_GENERAL_ADMIN_FUNCTION_CREATE_OQ                    0x11
 328 #define PQI_GENERAL_ADMIN_FUNCTION_DELETE_IQ                    0x12
 329 #define PQI_GENERAL_ADMIN_FUNCTION_DELETE_OQ                    0x13
 330 #define PQI_GENERAL_ADMIN_FUNCTION_CHANGE_IQ_PROPERTY           0x14
 331 
 332 #define PQI_GENERAL_ADMIN_STATUS_SUCCESS        0x0
 333 #define PQI_GENERAL_ADMIN_IU_LENGTH             0x3c
 334 #define PQI_PROTOCOL_SOP                        0x0
 335 
 336 #define PQI_IQ_PROPERTY_IS_AIO_QUEUE            0x1
 337 
 338 typedef struct pqi_iu_layer_descriptor {
 339         uint8_t         inbound_spanning_supported : 1;
 340         uint8_t         reserved : 7;
 341         uint8_t         reserved1[5];
 342         uint16_t        max_inbound_iu_length;
 343         uint8_t         outbound_spanning_supported : 1;
 344         uint8_t         reserved2 : 7;
 345         uint8_t         reserved3[5];
 346         uint16_t        max_outbound_iu_length;
 347 } pqi_iu_layer_descriptor_t;
 348 
 349 typedef struct pqi_device_capability {
 350         uint16_t        data_length;
 351         uint8_t         reserved[6];
 352         uint8_t         iq_arbitration_priority_support_bitmask;
 353         uint8_t         maximum_aw_a;
 354         uint8_t         maximum_aw_b;
 355         uint8_t         maximum_aw_c;
 356         uint8_t         max_arbitration_burst : 3;
 357         uint8_t         reserved1 : 4;
 358         uint8_t         iqa : 1;
 359         uint8_t         reserved2[2];
 360         uint8_t         iq_freeze : 1;
 361         uint8_t         reserved3 : 7;
 362         uint16_t        max_inbound_queues;
 363         uint16_t        max_elements_per_iq;
 364         uint8_t         reserved4[4];
 365         uint16_t        max_iq_element_length;
 366         uint16_t        min_iq_element_length;
 367         uint8_t         reserved5[2];
 368         uint16_t        max_outbound_queues;
 369         uint16_t        max_elements_per_oq;
 370         uint16_t        intr_coalescing_time_granularity;
 371         uint16_t        max_oq_element_length;
 372         uint16_t        min_oq_element_length;
 373         uint8_t         reserved6[24];
 374         pqi_iu_layer_descriptor_t iu_layer_descriptors[32];
 375 } pqi_device_capability_t;
 376 
 377 typedef struct pqi_general_management_request {
 378         pqi_iu_header_t header;
 379         uint16_t  request_id;
 380         union {
 381                 struct {
 382                         uint8_t         reserved[2];
 383                         uint32_t        buffer_length;
 384                         pqi_sg_entry_t  sg_descriptors[3];
 385                 } report_event_configuration;
 386 
 387                 struct {
 388                         uint16_t        global_event_oq_id;
 389                         uint32_t        buffer_length;
 390                         pqi_sg_entry_t  sg_descriptors[3];
 391                 } set_event_configuration;
 392         } data;
 393 } pqi_general_mgmt_rqst_t;
 394 
 395 #define RAID_CTLR_LUNID         "\0\0\0\0\0\0\0\0"
 396 
 397 typedef struct pqi_config_table {
 398         uint8_t         signature[8];           /* "CFGTABLE" */
 399         /* offset in bytes from the base address of this table to the */
 400         /* first section */
 401         uint32_t        first_section_offset;
 402 } pqi_config_table_t;
 403 
 404 typedef struct pqi_config_table_section_header {
 405         /* as defined by the PQI_CONFIG_TABLE_SECTION_* manifest */
 406         /* constants above */
 407         uint16_t        section_id;
 408 
 409         /* offset in bytes from base address of the table of the */
 410         /* next section or 0 if last entry */
 411         uint16_t        next_section_offset;
 412 } pqi_config_table_section_header_t;
 413 
 414 struct pqi_config_table_general_info {
 415         pqi_config_table_section_header_t       header;
 416 
 417         /* size of this section in bytes including the section header */
 418         uint32_t        section_length;
 419 
 420         /* max. outstanding commands supported by the controller */
 421         uint32_t        max_outstanding_requests;
 422 
 423         /* max. transfer size of a single command */
 424         uint32_t        max_sg_size;
 425 
 426         /* max. number of scatter-gather entries supported in a single cmd */
 427         uint32_t        max_sg_per_request;
 428 };
 429 
 430 typedef struct pqi_config_table_heartbeat {
 431         pqi_config_table_section_header_t       header;
 432         uint32_t                                heartbeat_counter;
 433 } pqi_config_table_heartbeat_t;
 434 
 435 typedef struct pqi_general_admin_request {
 436         pqi_iu_header_t header;
 437         uint16_t        request_id;
 438         uint8_t         function_code;
 439         union {
 440                 struct {
 441                         uint8_t         reserved[33];
 442                         uint32_t        buffer_length;
 443                         pqi_sg_entry_t  sg_descriptor;
 444                 } report_device_capability;
 445 
 446                 struct {
 447                         uint8_t         reserved;
 448                         uint16_t        queue_id;
 449                         uint8_t         reserved1[2];
 450                         uint64_t        element_array_addr;
 451                         uint64_t        ci_addr;
 452                         uint16_t        num_elements;
 453                         uint16_t        element_length;
 454                         uint8_t         queue_protocol;
 455                         uint8_t         reserved2[23];
 456                         uint32_t        vendor_specific;
 457                 } create_operational_iq;
 458 
 459                 struct {
 460                         uint8_t         reserved;
 461                         uint16_t        queue_id;
 462                         uint8_t         reserved1[2];
 463                         uint64_t        element_array_addr;
 464                         uint64_t        pi_addr;
 465                         uint16_t        num_elements;
 466                         uint16_t        element_length;
 467                         uint8_t         queue_protocol;
 468                         uint8_t         reserved2[3];
 469                         uint16_t        int_msg_num;
 470                         uint16_t        coalescing_count;
 471                         uint32_t        min_coalescing_time;
 472                         uint32_t        max_coalescing_time;
 473                         uint8_t         reserved3[8];
 474                         uint32_t        vendor_specific;
 475                 } create_operational_oq;
 476 
 477                 struct {
 478                         uint8_t         reserved;
 479                         uint16_t        queue_id;
 480                         uint8_t         reserved1[50];
 481                 } delete_operational_queue;
 482 
 483                 struct {
 484                         uint8_t         reserved;
 485                         uint16_t        queue_id;
 486                         uint8_t         reserved1[46];
 487                         uint32_t        vendor_specific;
 488                 } change_operational_iq_properties;
 489 
 490         } data;
 491 } pqi_general_admin_request_t;
 492 
 493 #define PQI_RESPONSE_IU_GENERAL_MANAGEMENT              0x81
 494 #define PQI_RESPONSE_IU_TASK_MANAGEMENT                 0x93
 495 #define PQI_RESPONSE_IU_GENERAL_ADMIN                   0xe0
 496 #define PQI_RESPONSE_IU_RAID_PATH_IO_SUCCESS            0xf0
 497 #define PQI_RESPONSE_IU_AIO_PATH_IO_SUCCESS             0xf1
 498 #define PQI_RESPONSE_IU_RAID_PATH_IO_ERROR              0xf2
 499 #define PQI_RESPONSE_IU_AIO_PATH_IO_ERROR               0xf3
 500 #define PQI_RESPONSE_IU_AIO_PATH_DISABLED               0xf4
 501 #define PQI_RESPONSE_IU_VENDOR_EVENT                    0xf5
 502 
 503 typedef struct pqi_general_admin_response {
 504         pqi_iu_header_t header;
 505         uint16_t        request_id;
 506         uint8_t         function_code;
 507         uint8_t         status;
 508         union {
 509                 struct {
 510                         uint8_t         status_descriptor[4];
 511                         uint64_t        iq_pi_offset;
 512                         uint8_t         reserved[40];
 513                 } create_operational_iq;
 514 
 515                 struct {
 516                         uint8_t         status_descriptor[4];
 517                         uint64_t        oq_ci_offset;
 518                         uint8_t         reserved[40];
 519                 } create_operational_oq;
 520         } data;
 521 } pqi_general_admin_response_t;
 522 
 523 typedef struct pqi_task_management_rqst {
 524         pqi_iu_header_t header;
 525         uint16_t        request_id;
 526         uint16_t        nexus_id;
 527         uint8_t         reserved[4];
 528         uint8_t         lun_number[8];
 529         uint16_t        protocol_specific;
 530         uint16_t        outbound_queue_id_to_manage;
 531         uint16_t        request_id_to_manage;
 532         uint8_t         task_management_function;
 533         uint8_t         reserved2 : 7;
 534         uint8_t         fence : 1;
 535 } pqi_task_management_rqst_t;
 536 
 537 /* ---- Support event types ---- */
 538 #define PQI_EVENT_TYPE_HOTPLUG                  0x1
 539 #define PQI_EVENT_TYPE_HARDWARE                 0x2
 540 #define PQI_EVENT_TYPE_PHYSICAL_DEVICE          0x4
 541 #define PQI_EVENT_TYPE_LOGICAL_DEVICE           0x5
 542 #define PQI_EVENT_TYPE_AIO_STATE_CHANGE         0xfd
 543 #define PQI_EVENT_TYPE_AIO_CONFIG_CHANGE                0xfe
 544 #define PQI_EVENT_TYPE_HEARTBEAT                        0xff
 545 
 546 typedef struct pqi_event_response {
 547         pqi_iu_header_t header;
 548         uint8_t         event_type;
 549         uint8_t         reserved2 : 7;
 550         uint8_t         request_acknowlege : 1;
 551         uint16_t        event_id;
 552         uint32_t        additional_event_id;
 553         uint8_t         data[16];
 554 } pqi_event_response_t;
 555 
 556 typedef struct pqi_event_acknowledge_request {
 557         pqi_iu_header_t header;
 558         uint8_t         event_type;
 559         uint8_t         reserved2;
 560         uint16_t        event_id;
 561         uint32_t        additional_event_id;
 562 } pqi_event_acknowledge_request_t;
 563 
 564 typedef struct pqi_event_descriptor {
 565         uint8_t         event_type;
 566         uint8_t         reserved;
 567         uint16_t        oq_id;
 568 } pqi_event_descriptor_t;
 569 
 570 typedef struct pqi_event_config {
 571         uint8_t                 reserved[2];
 572         uint8_t                 num_event_descriptors;
 573         uint8_t                 reserved1;
 574         pqi_event_descriptor_t  descriptors[1];
 575 } pqi_event_config_t;
 576 
 577 typedef struct bmic_identify_controller {
 578         uint8_t         configured_logical_drive_count;
 579         uint32_t        configuration_signature;
 580         uint8_t         firmware_version[4];
 581         uint8_t         reserved[145];
 582         uint16_t        extended_logical_unit_count;
 583         uint8_t         reserved1[34];
 584         uint16_t        firmware_build_number;
 585         uint8_t         reserved2[100];
 586         uint8_t         controller_mode;
 587         uint8_t         reserved3[32];
 588 } bmic_identify_controller_t;
 589 
 590 #define CISS_GET_LEVEL_2_BUS(lunid)             ((lunid)[7] & 0x3f)
 591 #define CISS_GET_LEVEL_2_TARGET(lunid)          ((lunid)[6])
 592 #define CISS_GET_DRIVE_NUMBER(lunid)            \
 593         (((CISS_GET_LEVEL_2_BUS((lunid)) - 1) << 8) + \
 594         CISS_GET_LEVEL_2_TARGET((lunid)))
 595 
 596 typedef struct bmic_identify_physical_device {
 597         uint8_t         scsi_bus;       /* SCSI Bus number on controller */
 598         uint8_t         scsi_id;        /* SCSI ID on this bus */
 599         uint16_t        block_size;     /* sector size in bytes */
 600         uint32_t        total_blocks;   /* number for sectors on drive */
 601         uint32_t        reserved_blocks;        /* controller reserved (RIS) */
 602         uint8_t         model[40];      /* Physical Drive Model */
 603         uint8_t         serial_number[40];      /* Drive Serial Number */
 604         uint8_t         firmware_revision[8];   /* drive firmware revision */
 605         uint8_t         scsi_inquiry_bits;      /* inquiry byte 7 bits */
 606         uint8_t         compaq_drive_stamp;     /* 0 means drive not stamped */
 607         uint8_t         last_failure_reason;
 608         uint8_t         flags;
 609         uint8_t         more_flags;
 610         uint8_t         scsi_lun;       /* SCSI LUN for phys drive */
 611         uint8_t         yet_more_flags;
 612         uint8_t         even_more_flags;
 613         uint32_t        spi_speed_rules;
 614         uint8_t         phys_connector[2]; /* connector number on controller */
 615         uint8_t         phys_box_on_bus; /* phys enclosure this drive resides */
 616         uint8_t         phys_bay_in_box; /* phys drv bay this drive resides */
 617         uint32_t        rpm;            /* drive rotational speed in RPM */
 618         uint8_t         device_type;    /* type of drive */
 619         uint8_t         sata_version;   /* only valid when device_type = */
 620         /* BMIC_DEVICE_TYPE_SATA */
 621         uint64_t        big_total_block_count;
 622         uint64_t        ris_starting_lba;
 623         uint32_t        ris_size;
 624         uint8_t         wwid[20];
 625         uint8_t         controller_phy_map[32];
 626         uint16_t        phy_count;
 627         uint8_t         phy_connected_dev_type[256];
 628         uint8_t         phy_to_drive_bay_num[256];
 629         uint16_t        phy_to_attached_dev_index[256];
 630         uint8_t         box_index;
 631         uint8_t         reserved;
 632         uint16_t        extra_physical_drive_flags;
 633         uint8_t         negotiated_link_rate[256];
 634         uint8_t         phy_to_phy_map[256];
 635         uint8_t         redundant_path_present_map;
 636         uint8_t         redundant_path_failure_map;
 637         uint8_t         active_path_number;
 638         uint16_t        alternate_paths_phys_connector[8];
 639         uint8_t         alternate_paths_phys_box_on_port[8];
 640         uint8_t         multi_lun_device_lun_count;
 641         uint8_t         minimum_good_fw_revision[8];
 642         uint8_t         unique_inquiry_bytes[20];
 643         uint8_t         current_temperature_degrees;
 644         uint8_t         temperature_threshold_degrees;
 645         uint8_t         max_temperature_degrees;
 646         uint8_t         logical_blocks_per_phys_block_exp;
 647         uint16_t        current_queue_depth_limit;
 648         uint8_t         switch_name[10];
 649         uint16_t        switch_port;
 650         uint8_t         alternate_paths_switch_name[40];
 651         uint8_t         alternate_paths_switch_port[8];
 652         uint16_t        power_on_hours;
 653         uint16_t        percent_endurance_used;
 654         uint8_t         drive_authentication;
 655         uint8_t         smart_carrier_authentication;
 656         uint8_t         smart_carrier_app_fw_version;
 657         uint8_t         smart_carrier_bootloader_fw_version;
 658         uint8_t         sanitize_flags;
 659         uint8_t         encryption_key_flags;
 660         uint8_t         encryption_key_name[64];
 661         uint32_t        misc_drive_flags;
 662         uint16_t        dek_index;
 663         uint16_t        hba_drive_encryption_flags;
 664         uint16_t        max_overwrite_time;
 665         uint16_t        max_block_erase_time;
 666         uint16_t        max_crypto_erase_time;
 667         uint8_t         connector_info[5];
 668         uint8_t         connector_name[8][8];
 669         uint8_t         page_83_identifier[16];
 670         uint8_t         maximum_link_rate[256];
 671         uint8_t         negotiated_physical_link_rate[256];
 672         uint8_t         box_connector_name[8];
 673         uint8_t padding_to_multiple_of_512[9];
 674 } bmic_identify_physical_device_t;
 675 
 676 typedef struct bmic_host_wellness_driver_version {
 677         uint8_t         start_tag[4];
 678         uint8_t         drv_tag[2];
 679         uint16_t        driver_version_length;
 680         char            driver_version[32];
 681         uint8_t         end_tag[2];
 682 } bmic_host_wellness_driver_version_t;
 683 
 684 typedef struct bmic_host_wellness_time {
 685         uint8_t         start_tag[4];
 686         uint8_t         time_tag[2];
 687         uint16_t        time_length;
 688         uint8_t         time[8];
 689         uint8_t         dont_write_tag[2];
 690         uint8_t         end_tag[2];
 691 } bmic_host_wellness_time_t;
 692 
 693 #define PQI_MAX_EVENT_DESCRIPTORS       255
 694 
 695 typedef struct report_lun_header {
 696         uint32_t        list_length;
 697         uint8_t         extended_response;
 698         uint8_t         reserved[3];
 699 } report_lun_header_t;
 700 
 701 typedef struct report_log_lun_extended_entry {
 702         uint8_t         lunid[8];
 703         uint8_t         volume_id[16];
 704 } report_log_lun_extended_entry_t;
 705 
 706 typedef struct report_log_lun_extended {
 707         report_lun_header_t             header;
 708         report_log_lun_extended_entry_t lun_entries[1];
 709 } report_log_lun_extended_t;
 710 
 711 typedef struct report_phys_lun_extended_entry {
 712         uint8_t         lunid[8];
 713         uint64_t        wwid;
 714         uint8_t         device_type;
 715         uint8_t         device_flags;
 716         uint8_t         lun_count; /* number of LUNs in a multi-LUN device */
 717         uint8_t         redundant_paths;
 718         uint32_t        aio_handle;
 719 } report_phys_lun_extended_entry_t;
 720 
 721 /* ---- Zoned Block Device ---- */
 722 #define TYPE_ZBC        0x14
 723 
 724 /* for device_flags field of struct report_phys_lun_extended_entry */
 725 #define REPORT_PHYS_LUN_DEV_FLAG_AIO_ENABLED    0x8
 726 
 727 typedef struct report_phys_lun_extended {
 728         report_lun_header_t                     header;
 729         report_phys_lun_extended_entry_t        lun_entries[1];
 730 } report_phys_lun_extended_t;
 731 #pragma pack()
 732 
 733 #ifdef __cplusplus
 734 }
 735 #endif
 736 
 737 #endif /* _SMARTPQI_HW_H */