1*1e66f787SSean Bruno /*- 2*1e66f787SSean Bruno * Copyright (c) 2018 Microsemi Corporation. 3*1e66f787SSean Bruno * All rights reserved. 4*1e66f787SSean Bruno * 5*1e66f787SSean Bruno * Redistribution and use in source and binary forms, with or without 6*1e66f787SSean Bruno * modification, are permitted provided that the following conditions 7*1e66f787SSean Bruno * are met: 8*1e66f787SSean Bruno * 1. Redistributions of source code must retain the above copyright 9*1e66f787SSean Bruno * notice, this list of conditions and the following disclaimer. 10*1e66f787SSean Bruno * 2. Redistributions in binary form must reproduce the above copyright 11*1e66f787SSean Bruno * notice, this list of conditions and the following disclaimer in the 12*1e66f787SSean Bruno * documentation and/or other materials provided with the distribution. 13*1e66f787SSean Bruno * 14*1e66f787SSean Bruno * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*1e66f787SSean Bruno * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*1e66f787SSean Bruno * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*1e66f787SSean Bruno * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*1e66f787SSean Bruno * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*1e66f787SSean Bruno * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*1e66f787SSean Bruno * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*1e66f787SSean Bruno * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*1e66f787SSean Bruno * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*1e66f787SSean Bruno * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*1e66f787SSean Bruno * SUCH DAMAGE. 25*1e66f787SSean Bruno */ 26*1e66f787SSean Bruno 27*1e66f787SSean Bruno /* $FreeBSD$ */ 28*1e66f787SSean Bruno 29*1e66f787SSean Bruno #ifndef _PQI_STRUCTURES_H 30*1e66f787SSean Bruno #define _PQI_STRUCTURES_H 31*1e66f787SSean Bruno 32*1e66f787SSean Bruno 33*1e66f787SSean Bruno 34*1e66f787SSean Bruno 35*1e66f787SSean Bruno struct bmic_host_wellness_driver_version { 36*1e66f787SSean Bruno uint8_t start_tag[4]; 37*1e66f787SSean Bruno uint8_t driver_version_tag[2]; 38*1e66f787SSean Bruno uint16_t driver_version_length; 39*1e66f787SSean Bruno char driver_version[32]; 40*1e66f787SSean Bruno uint8_t end_tag[2]; 41*1e66f787SSean Bruno 42*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 43*1e66f787SSean Bruno 44*1e66f787SSean Bruno 45*1e66f787SSean Bruno struct bmic_host_wellness_time { 46*1e66f787SSean Bruno uint8_t start_tag[4]; 47*1e66f787SSean Bruno uint8_t time_tag[2]; 48*1e66f787SSean Bruno uint16_t time_length; 49*1e66f787SSean Bruno uint8_t hour; 50*1e66f787SSean Bruno uint8_t min; 51*1e66f787SSean Bruno uint8_t sec; 52*1e66f787SSean Bruno uint8_t reserved; 53*1e66f787SSean Bruno uint8_t month; 54*1e66f787SSean Bruno uint8_t day; 55*1e66f787SSean Bruno uint8_t century; 56*1e66f787SSean Bruno uint8_t year; 57*1e66f787SSean Bruno uint8_t dont_write_tag[2]; 58*1e66f787SSean Bruno uint8_t end_tag[2]; 59*1e66f787SSean Bruno 60*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 61*1e66f787SSean Bruno 62*1e66f787SSean Bruno 63*1e66f787SSean Bruno /* As per PQI Spec pqi-2r00a , 6.2.2. */ 64*1e66f787SSean Bruno 65*1e66f787SSean Bruno /* device capability register , for admin q table 24 */ 66*1e66f787SSean Bruno struct pqi_dev_adminq_cap { 67*1e66f787SSean Bruno uint8_t max_admin_ibq_elem; 68*1e66f787SSean Bruno uint8_t max_admin_obq_elem; 69*1e66f787SSean Bruno uint8_t admin_ibq_elem_len; 70*1e66f787SSean Bruno uint8_t admin_obq_elem_len; 71*1e66f787SSean Bruno uint16_t max_pqi_dev_reset_tmo; 72*1e66f787SSean Bruno uint8_t res[2]; 73*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 74*1e66f787SSean Bruno 75*1e66f787SSean Bruno /* admin q parameter reg , table 36 */ 76*1e66f787SSean Bruno struct admin_q_param { 77*1e66f787SSean Bruno uint8_t num_iq_elements; 78*1e66f787SSean Bruno uint8_t num_oq_elements; 79*1e66f787SSean Bruno uint8_t intr_msg_num; 80*1e66f787SSean Bruno uint8_t msix_disable; 81*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 82*1e66f787SSean Bruno 83*1e66f787SSean Bruno struct pqi_registers { 84*1e66f787SSean Bruno uint64_t signature; 85*1e66f787SSean Bruno uint64_t admin_q_config; 86*1e66f787SSean Bruno uint64_t pqi_dev_adminq_cap; 87*1e66f787SSean Bruno uint32_t legacy_intr_status; 88*1e66f787SSean Bruno uint32_t legacy_intr_mask_set; 89*1e66f787SSean Bruno uint32_t legacy_intr_mask_clr; 90*1e66f787SSean Bruno uint8_t res1[28]; 91*1e66f787SSean Bruno uint32_t pqi_dev_status; 92*1e66f787SSean Bruno uint8_t res2[4]; 93*1e66f787SSean Bruno uint64_t admin_ibq_pi_offset; 94*1e66f787SSean Bruno uint64_t admin_obq_ci_offset; 95*1e66f787SSean Bruno uint64_t admin_ibq_elem_array_addr; 96*1e66f787SSean Bruno uint64_t admin_obq_elem_array_addr; 97*1e66f787SSean Bruno uint64_t admin_ibq_ci_addr; 98*1e66f787SSean Bruno uint64_t admin_obq_pi_addr; 99*1e66f787SSean Bruno uint32_t admin_q_param; 100*1e66f787SSean Bruno uint8_t res3[4]; 101*1e66f787SSean Bruno uint32_t pqi_dev_err; 102*1e66f787SSean Bruno uint8_t res4[4]; 103*1e66f787SSean Bruno uint64_t error_details; 104*1e66f787SSean Bruno uint32_t dev_reset; 105*1e66f787SSean Bruno uint32_t power_action; 106*1e66f787SSean Bruno uint8_t res5[104]; 107*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 108*1e66f787SSean Bruno 109*1e66f787SSean Bruno /* 110*1e66f787SSean Bruno * IOA controller registers 111*1e66f787SSean Bruno * Mapped in PCIe BAR 0. 112*1e66f787SSean Bruno */ 113*1e66f787SSean Bruno 114*1e66f787SSean Bruno struct ioa_registers { 115*1e66f787SSean Bruno uint8_t res1[0x18]; 116*1e66f787SSean Bruno uint32_t host_to_ioa_db_mask_clr; /* 18h */ 117*1e66f787SSean Bruno uint8_t res2[4]; 118*1e66f787SSean Bruno uint32_t host_to_ioa_db; /* 20h */ 119*1e66f787SSean Bruno uint8_t res3[4]; 120*1e66f787SSean Bruno uint32_t host_to_ioa_db_clr; /* 28h */ 121*1e66f787SSean Bruno uint8_t res4[8]; 122*1e66f787SSean Bruno uint32_t ioa_to_host_glob_int_mask; /* 34h */ 123*1e66f787SSean Bruno uint8_t res5[0x64]; 124*1e66f787SSean Bruno uint32_t ioa_to_host_db; /* 9Ch */ 125*1e66f787SSean Bruno uint32_t ioa_to_host_db_clr; /* A0h */ 126*1e66f787SSean Bruno uint8_t res6[4]; 127*1e66f787SSean Bruno uint32_t ioa_to_host_db_mask; /* A8h */ 128*1e66f787SSean Bruno uint32_t ioa_to_host_db_mask_clr; /* ACh */ 129*1e66f787SSean Bruno uint32_t scratchpad0; /* B0h */ 130*1e66f787SSean Bruno uint32_t scratchpad1; /* B4h */ 131*1e66f787SSean Bruno uint32_t scratchpad2; /* B8h */ 132*1e66f787SSean Bruno uint32_t scratchpad3_fw_status; /* BCh */ 133*1e66f787SSean Bruno uint8_t res7[8]; 134*1e66f787SSean Bruno uint32_t scratchpad4; /* C8h */ 135*1e66f787SSean Bruno uint8_t res8[0xf34]; /* 0xC8 + 4 + 0xf34 = 1000h */ 136*1e66f787SSean Bruno uint32_t mb[8]; /* 1000h */ 137*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 138*1e66f787SSean Bruno 139*1e66f787SSean Bruno 140*1e66f787SSean Bruno /* PQI Preferred settings */ 141*1e66f787SSean Bruno struct pqi_pref_settings { 142*1e66f787SSean Bruno uint16_t max_cmd_size; 143*1e66f787SSean Bruno uint16_t max_fib_size; 144*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 145*1e66f787SSean Bruno 146*1e66f787SSean Bruno /* pqi capability by sis interface */ 147*1e66f787SSean Bruno struct pqi_cap { 148*1e66f787SSean Bruno uint32_t max_sg_elem; 149*1e66f787SSean Bruno uint32_t max_transfer_size; 150*1e66f787SSean Bruno uint32_t max_outstanding_io; 151*1e66f787SSean Bruno uint32_t conf_tab_off; 152*1e66f787SSean Bruno uint32_t conf_tab_sz; 153*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 154*1e66f787SSean Bruno 155*1e66f787SSean Bruno struct pqi_conf_table { 156*1e66f787SSean Bruno uint8_t sign[8]; /* "CFGTABLE" */ 157*1e66f787SSean Bruno uint32_t first_section_off; 158*1e66f787SSean Bruno }; 159*1e66f787SSean Bruno 160*1e66f787SSean Bruno struct pqi_conf_table_section_header { 161*1e66f787SSean Bruno uint16_t section_id; 162*1e66f787SSean Bruno uint16_t next_section_off; 163*1e66f787SSean Bruno }; 164*1e66f787SSean Bruno 165*1e66f787SSean Bruno struct pqi_conf_table_general_info { 166*1e66f787SSean Bruno struct pqi_conf_table_section_header header; 167*1e66f787SSean Bruno uint32_t section_len; 168*1e66f787SSean Bruno uint32_t max_outstanding_req; 169*1e66f787SSean Bruno uint32_t max_sg_size; 170*1e66f787SSean Bruno uint32_t max_sg_per_req; 171*1e66f787SSean Bruno }; 172*1e66f787SSean Bruno 173*1e66f787SSean Bruno struct pqi_conf_table_debug { 174*1e66f787SSean Bruno struct pqi_conf_table_section_header header; 175*1e66f787SSean Bruno uint32_t scratchpad; 176*1e66f787SSean Bruno }; 177*1e66f787SSean Bruno 178*1e66f787SSean Bruno struct pqi_conf_table_heartbeat { 179*1e66f787SSean Bruno struct pqi_conf_table_section_header header; 180*1e66f787SSean Bruno uint32_t heartbeat_counter; 181*1e66f787SSean Bruno }; 182*1e66f787SSean Bruno 183*1e66f787SSean Bruno typedef union pqi_reset_reg { 184*1e66f787SSean Bruno struct { 185*1e66f787SSean Bruno uint32_t reset_type : 3; 186*1e66f787SSean Bruno uint32_t reserved : 2; 187*1e66f787SSean Bruno uint32_t reset_action : 3; 188*1e66f787SSean Bruno uint32_t hold_in_pd1 : 1; 189*1e66f787SSean Bruno uint32_t reserved2 : 23; 190*1e66f787SSean Bruno } bits; 191*1e66f787SSean Bruno uint32_t all_bits; 192*1e66f787SSean Bruno }pqi_reset_reg_t; 193*1e66f787SSean Bruno 194*1e66f787SSean Bruno /* Memory descriptor for DMA memory allocation */ 195*1e66f787SSean Bruno typedef struct dma_mem { 196*1e66f787SSean Bruno void *virt_addr; 197*1e66f787SSean Bruno dma_addr_t dma_addr; 198*1e66f787SSean Bruno uint32_t size; 199*1e66f787SSean Bruno uint32_t align; 200*1e66f787SSean Bruno char *tag; 201*1e66f787SSean Bruno bus_dma_tag_t dma_tag; 202*1e66f787SSean Bruno bus_dmamap_t dma_map; 203*1e66f787SSean Bruno }dma_mem_t; 204*1e66f787SSean Bruno 205*1e66f787SSean Bruno /* Lock should be 8 byte aligned */ 206*1e66f787SSean Bruno 207*1e66f787SSean Bruno #ifndef LOCKFREE_STACK 208*1e66f787SSean Bruno 209*1e66f787SSean Bruno typedef struct pqi_taglist { 210*1e66f787SSean Bruno uint32_t max_elem; 211*1e66f787SSean Bruno uint32_t num_elem; 212*1e66f787SSean Bruno uint32_t head; 213*1e66f787SSean Bruno uint32_t tail; 214*1e66f787SSean Bruno uint32_t *elem_array; 215*1e66f787SSean Bruno boolean_t lockcreated; 216*1e66f787SSean Bruno char lockname[LOCKNAME_SIZE]; 217*1e66f787SSean Bruno OS_LOCK_T lock OS_ATTRIBUTE_ALIGNED(8); 218*1e66f787SSean Bruno }pqi_taglist_t; 219*1e66f787SSean Bruno 220*1e66f787SSean Bruno #else /* LOCKFREE_STACK */ 221*1e66f787SSean Bruno 222*1e66f787SSean Bruno union head_list { 223*1e66f787SSean Bruno struct { 224*1e66f787SSean Bruno uint32_t seq_no; /* To avoid aba problem */ 225*1e66f787SSean Bruno uint32_t index; /* Index at the top of the stack */ 226*1e66f787SSean Bruno }top; 227*1e66f787SSean Bruno uint64_t data; 228*1e66f787SSean Bruno }; 229*1e66f787SSean Bruno /* lock-free stack used to push and pop the tag used for IO request */ 230*1e66f787SSean Bruno typedef struct lockless_stack { 231*1e66f787SSean Bruno uint32_t *next_index_array; 232*1e66f787SSean Bruno uint32_t num_elements; 233*1e66f787SSean Bruno volatile union head_list head OS_ATTRIBUTE_ALIGNED(8); 234*1e66f787SSean Bruno }lockless_stack_t; 235*1e66f787SSean Bruno 236*1e66f787SSean Bruno #endif /* LOCKFREE_STACK */ 237*1e66f787SSean Bruno 238*1e66f787SSean Bruno /* 239*1e66f787SSean Bruno * PQI SGL descriptor layouts. 240*1e66f787SSean Bruno */ 241*1e66f787SSean Bruno /* 242*1e66f787SSean Bruno * SGL (Scatter Gather List) descriptor Codes 243*1e66f787SSean Bruno */ 244*1e66f787SSean Bruno 245*1e66f787SSean Bruno #define SGL_DESCRIPTOR_CODE_DATA_BLOCK 0x0 246*1e66f787SSean Bruno #define SGL_DESCRIPTOR_CODE_BIT_BUCKET 0x1 247*1e66f787SSean Bruno #define SGL_DESCRIPTOR_CODE_STANDARD_SEGMENT 0x2 248*1e66f787SSean Bruno #define SGL_DESCRIPTOR_CODE_LAST_STANDARD_SEGMENT 0x3 249*1e66f787SSean Bruno #define SGL_DESCRIPTOR_CODE_LAST_ALTERNATIVE_SGL_SEGMENT 0x4 250*1e66f787SSean Bruno #define SGL_DESCRIPTOR_CODE_VENDOR_SPECIFIC 0xF 251*1e66f787SSean Bruno 252*1e66f787SSean Bruno typedef struct sgl_descriptor 253*1e66f787SSean Bruno { 254*1e66f787SSean Bruno uint64_t addr; /* !< Bytes 0-7. The starting 64-bit memory byte address of the data block. */ 255*1e66f787SSean Bruno uint32_t length; /* !< Bytes 8-11. The length in bytes of the data block. Set to 0x00000000 specifies that no data be transferred. */ 256*1e66f787SSean Bruno uint8_t res[3]; /* !< Bytes 12-14. */ 257*1e66f787SSean Bruno uint8_t zero : 4; /* !< Byte 15, Bits 0-3. */ 258*1e66f787SSean Bruno uint8_t type : 4; /* !< Byte 15, Bits 4-7. sgl descriptor type */ 259*1e66f787SSean Bruno } sg_desc_t; 260*1e66f787SSean Bruno 261*1e66f787SSean Bruno /* PQI IUs */ 262*1e66f787SSean Bruno typedef struct iu_header 263*1e66f787SSean Bruno { 264*1e66f787SSean Bruno uint8_t iu_type; 265*1e66f787SSean Bruno uint8_t comp_feature; 266*1e66f787SSean Bruno uint16_t iu_length; 267*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED iu_header_t; 268*1e66f787SSean Bruno 269*1e66f787SSean Bruno 270*1e66f787SSean Bruno typedef struct general_admin_request /* REPORT_PQI_DEVICE_CAPABILITY, REPORT_MANUFACTURER_INFO, REPORT_OPERATIONAL_IQ, REPORT_OPERATIONAL_OQ all same layout. */ 271*1e66f787SSean Bruno { 272*1e66f787SSean Bruno iu_header_t header; /* !< Bytes 0-3. */ 273*1e66f787SSean Bruno uint16_t res1; 274*1e66f787SSean Bruno uint16_t work; 275*1e66f787SSean Bruno uint16_t req_id; /* !< Bytes 8-9. request identifier */ 276*1e66f787SSean Bruno uint8_t fn_code; /* !< Byte 10. which administrator function */ 277*1e66f787SSean Bruno union { 278*1e66f787SSean Bruno struct { 279*1e66f787SSean Bruno uint8_t res2[33]; /* !< Bytes 11-43. function specific */ 280*1e66f787SSean Bruno uint32_t buf_size; /* !< Bytes 44-47. size in bytes of the Data-In/Out Buffer */ 281*1e66f787SSean Bruno sg_desc_t sg_desc; /* !< Bytes 48-63. SGL */ 282*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED general_func; 283*1e66f787SSean Bruno 284*1e66f787SSean Bruno struct { 285*1e66f787SSean Bruno uint8_t res1; 286*1e66f787SSean Bruno uint16_t qid; 287*1e66f787SSean Bruno uint8_t res2[2]; 288*1e66f787SSean Bruno uint64_t elem_arr_addr; 289*1e66f787SSean Bruno uint64_t iq_ci_addr; 290*1e66f787SSean Bruno uint16_t num_elem; 291*1e66f787SSean Bruno uint16_t elem_len; 292*1e66f787SSean Bruno uint8_t queue_proto; 293*1e66f787SSean Bruno uint8_t arb_prio; 294*1e66f787SSean Bruno uint8_t res3[22]; 295*1e66f787SSean Bruno uint32_t vend_specific; 296*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED create_op_iq; 297*1e66f787SSean Bruno 298*1e66f787SSean Bruno struct { 299*1e66f787SSean Bruno uint8_t res1; 300*1e66f787SSean Bruno uint16_t qid; 301*1e66f787SSean Bruno uint8_t res2[2]; 302*1e66f787SSean Bruno uint64_t elem_arr_addr; 303*1e66f787SSean Bruno uint64_t ob_pi_addr; 304*1e66f787SSean Bruno uint16_t num_elem; 305*1e66f787SSean Bruno uint16_t elem_len; 306*1e66f787SSean Bruno uint8_t queue_proto; 307*1e66f787SSean Bruno uint8_t res3[3]; 308*1e66f787SSean Bruno uint16_t intr_msg_num; 309*1e66f787SSean Bruno uint16_t coales_count; 310*1e66f787SSean Bruno uint32_t min_coales_time; 311*1e66f787SSean Bruno uint32_t max_coales_time; 312*1e66f787SSean Bruno uint8_t res4[8]; 313*1e66f787SSean Bruno uint32_t vend_specific; 314*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED create_op_oq; 315*1e66f787SSean Bruno 316*1e66f787SSean Bruno struct { 317*1e66f787SSean Bruno uint8_t res1; 318*1e66f787SSean Bruno uint16_t qid; 319*1e66f787SSean Bruno uint8_t res2[50]; 320*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED delete_op_queue; 321*1e66f787SSean Bruno 322*1e66f787SSean Bruno struct { 323*1e66f787SSean Bruno uint8_t res1; 324*1e66f787SSean Bruno uint16_t qid; 325*1e66f787SSean Bruno uint8_t res2[46]; 326*1e66f787SSean Bruno uint32_t vend_specific; 327*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED change_op_iq_prop; 328*1e66f787SSean Bruno 329*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED req_type; 330*1e66f787SSean Bruno 331*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED gen_adm_req_iu_t; 332*1e66f787SSean Bruno 333*1e66f787SSean Bruno 334*1e66f787SSean Bruno typedef struct general_admin_response { 335*1e66f787SSean Bruno iu_header_t header; 336*1e66f787SSean Bruno uint16_t res1; 337*1e66f787SSean Bruno uint16_t work; 338*1e66f787SSean Bruno uint16_t req_id; 339*1e66f787SSean Bruno uint8_t fn_code; 340*1e66f787SSean Bruno uint8_t status; 341*1e66f787SSean Bruno union { 342*1e66f787SSean Bruno struct { 343*1e66f787SSean Bruno uint8_t status_desc[4]; 344*1e66f787SSean Bruno uint64_t pi_offset; 345*1e66f787SSean Bruno uint8_t res[40]; 346*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED create_op_iq; 347*1e66f787SSean Bruno 348*1e66f787SSean Bruno struct { 349*1e66f787SSean Bruno uint8_t status_desc[4]; 350*1e66f787SSean Bruno uint64_t ci_offset; 351*1e66f787SSean Bruno uint8_t res[40]; 352*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED create_op_oq; 353*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED resp_type; 354*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED gen_adm_resp_iu_t ; 355*1e66f787SSean Bruno 356*1e66f787SSean Bruno /*report and set Event config IU*/ 357*1e66f787SSean Bruno 358*1e66f787SSean Bruno typedef struct pqi_event_config_request { 359*1e66f787SSean Bruno iu_header_t header; 360*1e66f787SSean Bruno uint16_t response_queue_id; /* specifies the OQ where the response 361*1e66f787SSean Bruno IU is to be delivered */ 362*1e66f787SSean Bruno uint8_t work_area[2]; /* reserved for driver use */ 363*1e66f787SSean Bruno uint16_t request_id; 364*1e66f787SSean Bruno union { 365*1e66f787SSean Bruno uint16_t reserved; /* Report event config iu */ 366*1e66f787SSean Bruno uint16_t global_event_oq_id; /* Set event config iu */ 367*1e66f787SSean Bruno }iu_specific; 368*1e66f787SSean Bruno uint32_t buffer_length; 369*1e66f787SSean Bruno sg_desc_t sg_desc; 370*1e66f787SSean Bruno }pqi_event_config_request_t; 371*1e66f787SSean Bruno #if 0 372*1e66f787SSean Bruno typedef struct pqi_set_event_config_request { 373*1e66f787SSean Bruno iu_header_t header; 374*1e66f787SSean Bruno uint16_t response_queue_id; /* specifies the OQ where the response 375*1e66f787SSean Bruno IU is to be delivered */ 376*1e66f787SSean Bruno uint8_t work_area[2]; /* reserved for driver use */ 377*1e66f787SSean Bruno uint16_t request_id; 378*1e66f787SSean Bruno uint16_t global_event_oq_id; 379*1e66f787SSean Bruno uint32_t buffer_length; 380*1e66f787SSean Bruno sg_desc_t sg_desc; 381*1e66f787SSean Bruno }pqi_set_event_config_request_t; 382*1e66f787SSean Bruno #endif 383*1e66f787SSean Bruno 384*1e66f787SSean Bruno /* Report/Set event config data-in/data-out buffer structure */ 385*1e66f787SSean Bruno 386*1e66f787SSean Bruno #define PQI_MAX_EVENT_DESCRIPTORS 255 387*1e66f787SSean Bruno 388*1e66f787SSean Bruno struct pqi_event_descriptor { 389*1e66f787SSean Bruno uint8_t event_type; 390*1e66f787SSean Bruno uint8_t reserved; 391*1e66f787SSean Bruno uint16_t oq_id; 392*1e66f787SSean Bruno }; 393*1e66f787SSean Bruno 394*1e66f787SSean Bruno typedef struct pqi_event_config { 395*1e66f787SSean Bruno uint8_t reserved[2]; 396*1e66f787SSean Bruno uint8_t num_event_descriptors; 397*1e66f787SSean Bruno uint8_t reserved1; 398*1e66f787SSean Bruno struct pqi_event_descriptor descriptors[PQI_MAX_EVENT_DESCRIPTORS]; 399*1e66f787SSean Bruno }pqi_event_config_t; 400*1e66f787SSean Bruno 401*1e66f787SSean Bruno /*management response IUs */ 402*1e66f787SSean Bruno typedef struct pqi_management_response{ 403*1e66f787SSean Bruno iu_header_t header; 404*1e66f787SSean Bruno uint16_t reserved1; 405*1e66f787SSean Bruno uint8_t work_area[2]; 406*1e66f787SSean Bruno uint16_t req_id; 407*1e66f787SSean Bruno uint8_t result; 408*1e66f787SSean Bruno uint8_t reserved[5]; 409*1e66f787SSean Bruno uint64_t result_data; 410*1e66f787SSean Bruno }pqi_management_response_t; 411*1e66f787SSean Bruno /*Event response IU*/ 412*1e66f787SSean Bruno typedef struct pqi_event_response { 413*1e66f787SSean Bruno iu_header_t header; 414*1e66f787SSean Bruno uint16_t reserved1; 415*1e66f787SSean Bruno uint8_t work_area[2]; 416*1e66f787SSean Bruno uint8_t event_type; 417*1e66f787SSean Bruno uint8_t reserved2 : 7; 418*1e66f787SSean Bruno uint8_t request_acknowledge : 1; 419*1e66f787SSean Bruno uint16_t event_id; 420*1e66f787SSean Bruno uint32_t additional_event_id; 421*1e66f787SSean Bruno uint8_t data[16]; 422*1e66f787SSean Bruno }pqi_event_response_t; 423*1e66f787SSean Bruno 424*1e66f787SSean Bruno /*event acknowledge IU*/ 425*1e66f787SSean Bruno typedef struct pqi_event_acknowledge_request { 426*1e66f787SSean Bruno iu_header_t header; 427*1e66f787SSean Bruno uint16_t reserved1; 428*1e66f787SSean Bruno uint8_t work_area[2]; 429*1e66f787SSean Bruno uint8_t event_type; 430*1e66f787SSean Bruno uint8_t reserved2; 431*1e66f787SSean Bruno uint16_t event_id; 432*1e66f787SSean Bruno uint32_t additional_event_id; 433*1e66f787SSean Bruno }pqi_event_acknowledge_request_t; 434*1e66f787SSean Bruno 435*1e66f787SSean Bruno struct pqi_event { 436*1e66f787SSean Bruno boolean_t pending; 437*1e66f787SSean Bruno uint8_t event_type; 438*1e66f787SSean Bruno uint16_t event_id; 439*1e66f787SSean Bruno uint32_t additional_event_id; 440*1e66f787SSean Bruno }; 441*1e66f787SSean Bruno 442*1e66f787SSean Bruno 443*1e66f787SSean Bruno typedef struct op_q_params 444*1e66f787SSean Bruno { 445*1e66f787SSean Bruno uint8_t fn_code; 446*1e66f787SSean Bruno uint16_t qid; 447*1e66f787SSean Bruno uint16_t num_elem; 448*1e66f787SSean Bruno uint16_t elem_len; 449*1e66f787SSean Bruno uint16_t int_msg_num; 450*1e66f787SSean Bruno 451*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED op_q_params; 452*1e66f787SSean Bruno 453*1e66f787SSean Bruno 454*1e66f787SSean Bruno /* Driver will use this structure to interpret the error 455*1e66f787SSean Bruno info element returned from a failed requests */ 456*1e66f787SSean Bruno typedef struct raid_path_error_info_elem { 457*1e66f787SSean Bruno uint8_t data_in_result; /* !< Byte 0. See SOP spec Table 77. */ 458*1e66f787SSean Bruno uint8_t data_out_result; /* !< Byte 1. See SOP spec Table 78. */ 459*1e66f787SSean Bruno uint8_t reserved[3]; /* !< Bytes 2-4. */ 460*1e66f787SSean Bruno uint8_t status; /* !< Byte 5. See SAM-5 specification "Status" codes Table 40. Defined in Storport.h */ 461*1e66f787SSean Bruno uint16_t status_qual; /* !< Bytes 6-7. See SAM-5 specification Table 43. */ 462*1e66f787SSean Bruno uint16_t sense_data_len; /* !< Bytes 8-9. See SOP specification table 79. */ 463*1e66f787SSean Bruno uint16_t resp_data_len; /* !< Bytes 10-11. See SOP specification table 79. */ 464*1e66f787SSean Bruno uint32_t data_in_transferred; /* !< Bytes 12-15. If "dada_in_result = 0x01 (DATA_IN BUFFER UNDERFLOW)", Indicates the number of contiguous bytes starting with offset zero in Data-In buffer else Ignored. */ 465*1e66f787SSean Bruno uint32_t data_out_transferred; /* !< Bytes 16-19. If "data_out_result = 0x01 (DATA_OUT BUFFER UNDERFLOW)", Indicates the number of contiguous bytes starting with offset zero in Data-Out buffer else Ignored. */ 466*1e66f787SSean Bruno uint8_t data[256]; /* !< Bytes 20-275. Response Data buffer or Sense Data buffer but not both. */ 467*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED raid_path_error_info_elem_t; 468*1e66f787SSean Bruno 469*1e66f787SSean Bruno #define PQI_ERROR_BUFFER_ELEMENT_LENGTH sizeof(raid_path_error_info_elem_t) 470*1e66f787SSean Bruno 471*1e66f787SSean Bruno typedef enum error_data_present 472*1e66f787SSean Bruno { 473*1e66f787SSean Bruno DATA_PRESENT_NO_DATA = 0, /* !< No data present in Data buffer. */ 474*1e66f787SSean Bruno DATA_PRESENT_RESPONSE_DATA = 1, /* !< Response data is present in Data buffer. */ 475*1e66f787SSean Bruno DATA_PRESENT_SENSE_DATA = 2 /* !< Sense data is present in Data buffer. */ 476*1e66f787SSean Bruno } error_data_present_t; 477*1e66f787SSean Bruno 478*1e66f787SSean Bruno typedef struct aio_path_error_info_elem 479*1e66f787SSean Bruno { 480*1e66f787SSean Bruno uint8_t status; /* !< Byte 0. See SAM-5 specification "SCSI Status" codes Table 40. Defined in Storport.h */ 481*1e66f787SSean Bruno uint8_t service_resp; /* !< Byte 1. SCSI Service Response. */ 482*1e66f787SSean Bruno uint8_t data_pres; /* !< Byte 2. Bits [7:2] reserved. Bits [1:0] - 0=No data, 1=Response data, 2=Sense data. */ 483*1e66f787SSean Bruno uint8_t reserved1; /* !< Byte 3. Reserved. */ 484*1e66f787SSean Bruno uint32_t resd_count; /* !< Bytes 4-7. The residual data length in bytes. Need the original transfer size and if Status is OverRun or UnderRun. */ 485*1e66f787SSean Bruno uint16_t data_len; /* !< Bytes 8-9. The amount of Sense data or Response data returned in Response/Sense Data buffer. */ 486*1e66f787SSean Bruno uint16_t reserved2; /* !< Bytes 10. Reserved. */ 487*1e66f787SSean Bruno uint8_t data[256]; /* !< Bytes 11-267. Response data buffer or Sense data buffer but not both. */ 488*1e66f787SSean Bruno uint8_t padding[8]; /* !< Bytes 268-275. Padding to make AIO_PATH_ERROR_INFO_ELEMENT = RAID_PATH_ERROR_INFO_ELEMENT */ 489*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED aio_path_error_info_elem_t; 490*1e66f787SSean Bruno 491*1e66f787SSean Bruno struct init_base_struct { 492*1e66f787SSean Bruno uint32_t revision; /* revision of init structure */ 493*1e66f787SSean Bruno uint32_t flags; /* reserved */ 494*1e66f787SSean Bruno uint32_t err_buf_paddr_l; /* lower 32 bits of physical address of error buffer */ 495*1e66f787SSean Bruno uint32_t err_buf_paddr_h; /* upper 32 bits of physical address of error buffer */ 496*1e66f787SSean Bruno uint32_t err_buf_elem_len; /* length of each element in error buffer (in bytes) */ 497*1e66f787SSean Bruno uint32_t err_buf_num_elem; /* number of elements in error buffer */ 498*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 499*1e66f787SSean Bruno 500*1e66f787SSean Bruno /* Queue details */ 501*1e66f787SSean Bruno typedef struct ib_queue { 502*1e66f787SSean Bruno uint32_t q_id; 503*1e66f787SSean Bruno uint32_t num_elem; 504*1e66f787SSean Bruno uint32_t elem_size; 505*1e66f787SSean Bruno char *array_virt_addr; 506*1e66f787SSean Bruno dma_addr_t array_dma_addr; 507*1e66f787SSean Bruno uint32_t pi_local; 508*1e66f787SSean Bruno uint32_t pi_register_offset; 509*1e66f787SSean Bruno uint32_t *pi_register_abs; 510*1e66f787SSean Bruno uint32_t *ci_virt_addr; 511*1e66f787SSean Bruno dma_addr_t ci_dma_addr; 512*1e66f787SSean Bruno boolean_t created; 513*1e66f787SSean Bruno boolean_t lockcreated; 514*1e66f787SSean Bruno char lockname[LOCKNAME_SIZE]; 515*1e66f787SSean Bruno OS_LOCK_T lock OS_ATTRIBUTE_ALIGNED(8); 516*1e66f787SSean Bruno }ib_queue_t; 517*1e66f787SSean Bruno 518*1e66f787SSean Bruno typedef struct ob_queue { 519*1e66f787SSean Bruno uint32_t q_id; 520*1e66f787SSean Bruno uint32_t num_elem; 521*1e66f787SSean Bruno uint32_t elem_size; 522*1e66f787SSean Bruno uint32_t intr_msg_num; 523*1e66f787SSean Bruno char *array_virt_addr; 524*1e66f787SSean Bruno dma_addr_t array_dma_addr; 525*1e66f787SSean Bruno uint32_t ci_local; 526*1e66f787SSean Bruno uint32_t ci_register_offset; 527*1e66f787SSean Bruno uint32_t *ci_register_abs; 528*1e66f787SSean Bruno uint32_t *pi_virt_addr; 529*1e66f787SSean Bruno dma_addr_t pi_dma_addr; 530*1e66f787SSean Bruno boolean_t created; 531*1e66f787SSean Bruno }ob_queue_t; 532*1e66f787SSean Bruno 533*1e66f787SSean Bruno typedef struct pqisrc_sg_desc{ 534*1e66f787SSean Bruno uint64_t addr; 535*1e66f787SSean Bruno uint32_t len; 536*1e66f787SSean Bruno uint32_t flags; 537*1e66f787SSean Bruno }sgt_t; 538*1e66f787SSean Bruno 539*1e66f787SSean Bruno 540*1e66f787SSean Bruno typedef struct pqi_iu_layer_desc { 541*1e66f787SSean Bruno uint8_t ib_spanning_supported : 1; 542*1e66f787SSean Bruno uint8_t res1 : 7; 543*1e66f787SSean Bruno uint8_t res2[5]; 544*1e66f787SSean Bruno uint16_t max_ib_iu_len; 545*1e66f787SSean Bruno uint8_t ob_spanning_supported : 1; 546*1e66f787SSean Bruno uint8_t res3 : 7; 547*1e66f787SSean Bruno uint8_t res4[5]; 548*1e66f787SSean Bruno uint16_t max_ob_iu_len; 549*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED pqi_iu_layer_desc_t; 550*1e66f787SSean Bruno 551*1e66f787SSean Bruno 552*1e66f787SSean Bruno /* Response IU data */ 553*1e66f787SSean Bruno typedef struct pqi_device_capabilities { 554*1e66f787SSean Bruno uint16_t length; 555*1e66f787SSean Bruno uint8_t res1[6]; 556*1e66f787SSean Bruno uint8_t ibq_arb_priority_support_bitmask; 557*1e66f787SSean Bruno uint8_t max_aw_a; 558*1e66f787SSean Bruno uint8_t max_aw_b; 559*1e66f787SSean Bruno uint8_t max_aw_c; 560*1e66f787SSean Bruno uint8_t max_arb_burst : 3; 561*1e66f787SSean Bruno uint8_t res2 : 4; 562*1e66f787SSean Bruno uint8_t iqa : 1; 563*1e66f787SSean Bruno uint8_t res3[2]; 564*1e66f787SSean Bruno uint8_t iq_freeze : 1; 565*1e66f787SSean Bruno uint8_t res4 : 7; 566*1e66f787SSean Bruno uint16_t max_iqs; 567*1e66f787SSean Bruno uint16_t max_iq_elements; 568*1e66f787SSean Bruno uint8_t res5[4]; 569*1e66f787SSean Bruno uint16_t max_iq_elem_len; 570*1e66f787SSean Bruno uint16_t min_iq_elem_len; 571*1e66f787SSean Bruno uint8_t res6[2]; 572*1e66f787SSean Bruno uint16_t max_oqs; 573*1e66f787SSean Bruno uint16_t max_oq_elements; 574*1e66f787SSean Bruno uint16_t intr_coales_time_granularity; 575*1e66f787SSean Bruno uint16_t max_oq_elem_len; 576*1e66f787SSean Bruno uint16_t min_oq_elem_len; 577*1e66f787SSean Bruno uint8_t res7[24]; 578*1e66f787SSean Bruno pqi_iu_layer_desc_t iu_layer_desc[32]; 579*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED pqi_dev_cap_t; 580*1e66f787SSean Bruno 581*1e66f787SSean Bruno /* IO path */ 582*1e66f787SSean Bruno 583*1e66f787SSean Bruno typedef struct pqi_aio_req { 584*1e66f787SSean Bruno iu_header_t header; 585*1e66f787SSean Bruno uint16_t response_queue_id; 586*1e66f787SSean Bruno uint8_t work_area[2]; 587*1e66f787SSean Bruno uint16_t req_id; 588*1e66f787SSean Bruno uint8_t res1[2]; 589*1e66f787SSean Bruno uint32_t nexus; 590*1e66f787SSean Bruno uint32_t buf_len; 591*1e66f787SSean Bruno uint8_t data_dir : 2; 592*1e66f787SSean Bruno uint8_t partial : 1; 593*1e66f787SSean Bruno uint8_t mem_type : 1; 594*1e66f787SSean Bruno uint8_t fence : 1; 595*1e66f787SSean Bruno uint8_t encrypt_enable : 1; 596*1e66f787SSean Bruno uint8_t res2 : 2; 597*1e66f787SSean Bruno uint8_t task_attr : 3; 598*1e66f787SSean Bruno uint8_t cmd_prio : 4; 599*1e66f787SSean Bruno uint8_t res3 : 1; 600*1e66f787SSean Bruno uint16_t encrypt_key_index; 601*1e66f787SSean Bruno uint32_t encrypt_twk_low; 602*1e66f787SSean Bruno uint32_t encrypt_twk_high; 603*1e66f787SSean Bruno uint8_t cdb[16]; 604*1e66f787SSean Bruno uint16_t err_idx; 605*1e66f787SSean Bruno uint8_t num_sg; 606*1e66f787SSean Bruno uint8_t cdb_len; 607*1e66f787SSean Bruno uint8_t lun[8]; 608*1e66f787SSean Bruno uint8_t res4[4]; 609*1e66f787SSean Bruno sgt_t sg_desc[4]; 610*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED pqi_aio_req_t; 611*1e66f787SSean Bruno 612*1e66f787SSean Bruno 613*1e66f787SSean Bruno typedef struct pqisrc_raid_request { 614*1e66f787SSean Bruno iu_header_t header; 615*1e66f787SSean Bruno uint16_t response_queue_id; /* specifies the OQ where the response 616*1e66f787SSean Bruno IU is to be delivered */ 617*1e66f787SSean Bruno uint8_t work_area[2]; /* reserved for driver use */ 618*1e66f787SSean Bruno uint16_t request_id; 619*1e66f787SSean Bruno uint16_t nexus_id; 620*1e66f787SSean Bruno uint32_t buffer_length; 621*1e66f787SSean Bruno uint8_t lun_number[8]; 622*1e66f787SSean Bruno uint16_t protocol_spec; 623*1e66f787SSean Bruno uint8_t data_direction : 2; 624*1e66f787SSean Bruno uint8_t partial : 1; 625*1e66f787SSean Bruno uint8_t reserved1 : 4; 626*1e66f787SSean Bruno uint8_t fence : 1; 627*1e66f787SSean Bruno uint16_t error_index; 628*1e66f787SSean Bruno uint8_t reserved2; 629*1e66f787SSean Bruno uint8_t task_attribute : 3; 630*1e66f787SSean Bruno uint8_t command_priority : 4; 631*1e66f787SSean Bruno uint8_t reserved3 : 1; 632*1e66f787SSean Bruno uint8_t reserved4 : 2; 633*1e66f787SSean Bruno uint8_t additional_cdb_bytes_usage : 3; 634*1e66f787SSean Bruno uint8_t reserved5 : 3; 635*1e66f787SSean Bruno uint8_t cdb[16]; 636*1e66f787SSean Bruno uint8_t additional_cdb_bytes[16]; 637*1e66f787SSean Bruno sgt_t sg_descriptors[4]; 638*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED pqisrc_raid_req_t; 639*1e66f787SSean Bruno 640*1e66f787SSean Bruno 641*1e66f787SSean Bruno typedef struct pqi_tmf_req { 642*1e66f787SSean Bruno iu_header_t header; 643*1e66f787SSean Bruno uint16_t resp_qid; 644*1e66f787SSean Bruno uint8_t work_area[2]; 645*1e66f787SSean Bruno uint16_t req_id; 646*1e66f787SSean Bruno uint16_t nexus; 647*1e66f787SSean Bruno uint8_t res1[4]; 648*1e66f787SSean Bruno uint8_t lun[8]; 649*1e66f787SSean Bruno uint16_t protocol_spec; 650*1e66f787SSean Bruno uint16_t obq_id_to_manage; 651*1e66f787SSean Bruno uint16_t req_id_to_manage; 652*1e66f787SSean Bruno uint8_t tmf; 653*1e66f787SSean Bruno uint8_t res2 : 7; 654*1e66f787SSean Bruno uint8_t fence : 1; 655*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED pqi_tmf_req_t; 656*1e66f787SSean Bruno 657*1e66f787SSean Bruno 658*1e66f787SSean Bruno typedef struct pqi_tmf_resp { 659*1e66f787SSean Bruno iu_header_t header; 660*1e66f787SSean Bruno uint16_t resp_qid; 661*1e66f787SSean Bruno uint8_t work_area[2]; 662*1e66f787SSean Bruno uint16_t req_id; 663*1e66f787SSean Bruno uint16_t nexus; 664*1e66f787SSean Bruno uint8_t add_resp_info[3]; 665*1e66f787SSean Bruno uint8_t resp_code; 666*1e66f787SSean Bruno }pqi_tmf_resp_t; 667*1e66f787SSean Bruno 668*1e66f787SSean Bruno 669*1e66f787SSean Bruno struct pqi_io_response { 670*1e66f787SSean Bruno iu_header_t header; 671*1e66f787SSean Bruno uint16_t queue_id; 672*1e66f787SSean Bruno uint8_t work_area[2]; 673*1e66f787SSean Bruno uint16_t request_id; 674*1e66f787SSean Bruno uint16_t error_index; 675*1e66f787SSean Bruno uint8_t reserved[4]; 676*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 677*1e66f787SSean Bruno 678*1e66f787SSean Bruno 679*1e66f787SSean Bruno struct pqi_enc_info { 680*1e66f787SSean Bruno uint16_t data_enc_key_index; 681*1e66f787SSean Bruno uint32_t encrypt_tweak_lower; 682*1e66f787SSean Bruno uint32_t encrypt_tweak_upper; 683*1e66f787SSean Bruno }; 684*1e66f787SSean Bruno 685*1e66f787SSean Bruno 686*1e66f787SSean Bruno typedef struct pqi_scsi_device { 687*1e66f787SSean Bruno device_type_t devtype; /* as reported by INQUIRY commmand */ 688*1e66f787SSean Bruno uint8_t device_type; /* as reported by 689*1e66f787SSean Bruno BMIC_IDENTIFY_PHYSICAL_DEVICE - only 690*1e66f787SSean Bruno valid for devtype = TYPE_DISK */ 691*1e66f787SSean Bruno int bus; 692*1e66f787SSean Bruno int target; 693*1e66f787SSean Bruno int lun; 694*1e66f787SSean Bruno uint8_t flags; 695*1e66f787SSean Bruno uint8_t scsi3addr[8]; 696*1e66f787SSean Bruno uint64_t wwid; 697*1e66f787SSean Bruno uint8_t is_physical_device : 1; 698*1e66f787SSean Bruno uint8_t is_external_raid_device : 1; 699*1e66f787SSean Bruno uint8_t target_lun_valid : 1; 700*1e66f787SSean Bruno uint8_t expose_device : 1; 701*1e66f787SSean Bruno uint8_t no_uld_attach : 1; 702*1e66f787SSean Bruno uint8_t is_obdr_device : 1; 703*1e66f787SSean Bruno uint8_t aio_enabled : 1; 704*1e66f787SSean Bruno uint8_t device_gone : 1; 705*1e66f787SSean Bruno uint8_t new_device : 1; 706*1e66f787SSean Bruno uint8_t volume_offline : 1; 707*1e66f787SSean Bruno uint8_t vendor[8]; /* bytes 8-15 of inquiry data */ 708*1e66f787SSean Bruno uint8_t model[16]; /* bytes 16-31 of inquiry data */ 709*1e66f787SSean Bruno uint64_t sas_address; 710*1e66f787SSean Bruno uint8_t raid_level; 711*1e66f787SSean Bruno uint16_t queue_depth; /* max. queue_depth for this device */ 712*1e66f787SSean Bruno uint16_t advertised_queue_depth; 713*1e66f787SSean Bruno uint32_t ioaccel_handle; 714*1e66f787SSean Bruno uint8_t volume_status; 715*1e66f787SSean Bruno uint8_t active_path_index; 716*1e66f787SSean Bruno uint8_t path_map; 717*1e66f787SSean Bruno uint8_t bay; 718*1e66f787SSean Bruno uint8_t box[8]; 719*1e66f787SSean Bruno uint16_t phys_connector[8]; 720*1e66f787SSean Bruno int offload_config; /* I/O accel RAID offload configured */ 721*1e66f787SSean Bruno int offload_enabled; /* I/O accel RAID offload enabled */ 722*1e66f787SSean Bruno int offload_enabled_pending; 723*1e66f787SSean Bruno int offload_to_mirror; /* Send next I/O accelerator RAID 724*1e66f787SSean Bruno offload request to mirror drive. */ 725*1e66f787SSean Bruno struct raid_map *raid_map; /* I/O accelerator RAID map */ 726*1e66f787SSean Bruno int reset_in_progress; 727*1e66f787SSean Bruno os_dev_info_t *dip; /*os specific scsi device information*/ 728*1e66f787SSean Bruno boolean_t invalid; 729*1e66f787SSean Bruno }pqi_scsi_dev_t; 730*1e66f787SSean Bruno 731*1e66f787SSean Bruno 732*1e66f787SSean Bruno struct sense_header_scsi { /* See SPC-3 section 4.5 */ 733*1e66f787SSean Bruno uint8_t response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */ 734*1e66f787SSean Bruno uint8_t sense_key; 735*1e66f787SSean Bruno uint8_t asc; 736*1e66f787SSean Bruno uint8_t ascq; 737*1e66f787SSean Bruno uint8_t byte4; 738*1e66f787SSean Bruno uint8_t byte5; 739*1e66f787SSean Bruno uint8_t byte6; 740*1e66f787SSean Bruno uint8_t additional_length; /* always 0 for fixed sense format */ 741*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED; 742*1e66f787SSean Bruno 743*1e66f787SSean Bruno 744*1e66f787SSean Bruno 745*1e66f787SSean Bruno typedef struct report_lun_header { 746*1e66f787SSean Bruno uint32_t list_length; 747*1e66f787SSean Bruno uint8_t extended_response; 748*1e66f787SSean Bruno uint8_t reserved[3]; 749*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED reportlun_header_t; 750*1e66f787SSean Bruno 751*1e66f787SSean Bruno 752*1e66f787SSean Bruno typedef struct report_lun_ext_entry { 753*1e66f787SSean Bruno uint8_t lunid[8]; 754*1e66f787SSean Bruno uint64_t wwid; 755*1e66f787SSean Bruno uint8_t device_type; 756*1e66f787SSean Bruno uint8_t device_flags; 757*1e66f787SSean Bruno uint8_t lun_count; /* number of LUNs in a multi-LUN device */ 758*1e66f787SSean Bruno uint8_t redundant_paths; 759*1e66f787SSean Bruno uint32_t ioaccel_handle; 760*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED reportlun_ext_entry_t; 761*1e66f787SSean Bruno 762*1e66f787SSean Bruno 763*1e66f787SSean Bruno typedef struct report_lun_data_ext { 764*1e66f787SSean Bruno reportlun_header_t header; 765*1e66f787SSean Bruno reportlun_ext_entry_t lun_entries[1]; 766*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED reportlun_data_ext_t; 767*1e66f787SSean Bruno 768*1e66f787SSean Bruno typedef struct raidmap_data { 769*1e66f787SSean Bruno uint32_t ioaccel_handle; 770*1e66f787SSean Bruno uint8_t xor_mult[2]; 771*1e66f787SSean Bruno uint8_t reserved[2]; 772*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED raidmap_data_t; 773*1e66f787SSean Bruno 774*1e66f787SSean Bruno typedef struct raid_map { 775*1e66f787SSean Bruno uint32_t structure_size; /* size of entire structure in bytes */ 776*1e66f787SSean Bruno uint32_t volume_blk_size; /* bytes / block in the volume */ 777*1e66f787SSean Bruno uint64_t volume_blk_cnt; /* logical blocks on the volume */ 778*1e66f787SSean Bruno uint8_t phys_blk_shift; /* shift factor to convert between 779*1e66f787SSean Bruno units of logical blocks and physical 780*1e66f787SSean Bruno disk blocks */ 781*1e66f787SSean Bruno uint8_t parity_rotation_shift; /* shift factor to convert between units 782*1e66f787SSean Bruno of logical stripes and physical 783*1e66f787SSean Bruno stripes */ 784*1e66f787SSean Bruno uint16_t strip_size; /* blocks used on each disk / stripe */ 785*1e66f787SSean Bruno uint64_t disk_starting_blk; /* first disk block used in volume */ 786*1e66f787SSean Bruno uint64_t disk_blk_cnt; /* disk blocks used by volume / disk */ 787*1e66f787SSean Bruno uint16_t data_disks_per_row; /* data disk entries / row in the map */ 788*1e66f787SSean Bruno uint16_t metadata_disks_per_row; /* mirror/parity disk entries / row 789*1e66f787SSean Bruno in the map */ 790*1e66f787SSean Bruno uint16_t row_cnt; /* rows in each layout map */ 791*1e66f787SSean Bruno uint16_t layout_map_count; /* layout maps (1 map per mirror/parity 792*1e66f787SSean Bruno group) */ 793*1e66f787SSean Bruno uint16_t flags; 794*1e66f787SSean Bruno uint16_t data_encryption_key_index; 795*1e66f787SSean Bruno uint8_t reserved[16]; 796*1e66f787SSean Bruno raidmap_data_t dev_data[RAID_MAP_MAX_ENTRIES]; 797*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED pqisrc_raid_map_t; 798*1e66f787SSean Bruno 799*1e66f787SSean Bruno 800*1e66f787SSean Bruno typedef struct bmic_ident_ctrl { 801*1e66f787SSean Bruno uint8_t conf_ld_count; 802*1e66f787SSean Bruno uint32_t conf_sign; 803*1e66f787SSean Bruno uint8_t fw_version[4]; 804*1e66f787SSean Bruno uint8_t rom_fw_rev[4]; 805*1e66f787SSean Bruno uint8_t hw_rev; 806*1e66f787SSean Bruno uint8_t reserved[140]; 807*1e66f787SSean Bruno uint16_t extended_lun_count; 808*1e66f787SSean Bruno uint8_t reserved1[34]; 809*1e66f787SSean Bruno uint16_t fw_build_number; 810*1e66f787SSean Bruno uint8_t reserved2[100]; 811*1e66f787SSean Bruno uint8_t ctrl_mode; 812*1e66f787SSean Bruno uint8_t reserved3[32]; 813*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED bmic_ident_ctrl_t; 814*1e66f787SSean Bruno 815*1e66f787SSean Bruno typedef struct bmic_identify_physical_device { 816*1e66f787SSean Bruno uint8_t scsi_bus; /* SCSI Bus number on controller */ 817*1e66f787SSean Bruno uint8_t scsi_id; /* SCSI ID on this bus */ 818*1e66f787SSean Bruno uint16_t block_size; /* sector size in bytes */ 819*1e66f787SSean Bruno uint32_t total_blocks; /* number for sectors on drive */ 820*1e66f787SSean Bruno uint32_t reserved_blocks; /* controller reserved (RIS) */ 821*1e66f787SSean Bruno uint8_t model[40]; /* Physical Drive Model */ 822*1e66f787SSean Bruno uint8_t serial_number[40]; /* Drive Serial Number */ 823*1e66f787SSean Bruno uint8_t firmware_revision[8]; /* drive firmware revision */ 824*1e66f787SSean Bruno uint8_t scsi_inquiry_bits; /* inquiry byte 7 bits */ 825*1e66f787SSean Bruno uint8_t compaq_drive_stamp; /* 0 means drive not stamped */ 826*1e66f787SSean Bruno uint8_t last_failure_reason; 827*1e66f787SSean Bruno uint8_t flags; 828*1e66f787SSean Bruno uint8_t more_flags; 829*1e66f787SSean Bruno uint8_t scsi_lun; /* SCSI LUN for phys drive */ 830*1e66f787SSean Bruno uint8_t yet_more_flags; 831*1e66f787SSean Bruno uint8_t even_more_flags; 832*1e66f787SSean Bruno uint32_t spi_speed_rules; 833*1e66f787SSean Bruno uint8_t phys_connector[2]; /* connector number on controller */ 834*1e66f787SSean Bruno uint8_t phys_box_on_bus; /* phys enclosure this drive resides */ 835*1e66f787SSean Bruno uint8_t phys_bay_in_box; /* phys drv bay this drive resides */ 836*1e66f787SSean Bruno uint32_t rpm; /* drive rotational speed in RPM */ 837*1e66f787SSean Bruno uint8_t device_type; /* type of drive */ 838*1e66f787SSean Bruno uint8_t sata_version; /* only valid when device_type = 839*1e66f787SSean Bruno BMIC_DEVICE_TYPE_SATA */ 840*1e66f787SSean Bruno uint64_t big_total_block_count; 841*1e66f787SSean Bruno uint64_t ris_starting_lba; 842*1e66f787SSean Bruno uint32_t ris_size; 843*1e66f787SSean Bruno uint8_t wwid[20]; 844*1e66f787SSean Bruno uint8_t controller_phy_map[32]; 845*1e66f787SSean Bruno uint16_t phy_count; 846*1e66f787SSean Bruno uint8_t phy_connected_dev_type[256]; 847*1e66f787SSean Bruno uint8_t phy_to_drive_bay_num[256]; 848*1e66f787SSean Bruno uint16_t phy_to_attached_dev_index[256]; 849*1e66f787SSean Bruno uint8_t box_index; 850*1e66f787SSean Bruno uint8_t reserved; 851*1e66f787SSean Bruno uint16_t extra_physical_drive_flags; 852*1e66f787SSean Bruno uint8_t negotiated_link_rate[256]; 853*1e66f787SSean Bruno uint8_t phy_to_phy_map[256]; 854*1e66f787SSean Bruno uint8_t redundant_path_present_map; 855*1e66f787SSean Bruno uint8_t redundant_path_failure_map; 856*1e66f787SSean Bruno uint8_t active_path_number; 857*1e66f787SSean Bruno uint16_t alternate_paths_phys_connector[8]; 858*1e66f787SSean Bruno uint8_t alternate_paths_phys_box_on_port[8]; 859*1e66f787SSean Bruno uint8_t multi_lun_device_lun_count; 860*1e66f787SSean Bruno uint8_t minimum_good_fw_revision[8]; 861*1e66f787SSean Bruno uint8_t unique_inquiry_bytes[20]; 862*1e66f787SSean Bruno uint8_t current_temperature_degreesC; 863*1e66f787SSean Bruno uint8_t temperature_threshold_degreesC; 864*1e66f787SSean Bruno uint8_t max_temperature_degreesC; 865*1e66f787SSean Bruno uint8_t logical_blocks_per_phys_block_exp; 866*1e66f787SSean Bruno uint16_t current_queue_depth_limit; 867*1e66f787SSean Bruno uint8_t switch_name[10]; 868*1e66f787SSean Bruno uint16_t switch_port; 869*1e66f787SSean Bruno uint8_t alternate_paths_switch_name[40]; 870*1e66f787SSean Bruno uint8_t alternate_paths_switch_port[8]; 871*1e66f787SSean Bruno uint16_t power_on_hours; 872*1e66f787SSean Bruno uint16_t percent_endurance_used; 873*1e66f787SSean Bruno uint8_t drive_authentication; 874*1e66f787SSean Bruno uint8_t smart_carrier_authentication; 875*1e66f787SSean Bruno uint8_t smart_carrier_app_fw_version; 876*1e66f787SSean Bruno uint8_t smart_carrier_bootloader_fw_version; 877*1e66f787SSean Bruno uint8_t encryption_key_name[64]; 878*1e66f787SSean Bruno uint32_t misc_drive_flags; 879*1e66f787SSean Bruno uint16_t dek_index; 880*1e66f787SSean Bruno uint8_t padding[112]; 881*1e66f787SSean Bruno }OS_ATTRIBUTE_PACKED bmic_ident_physdev_t; 882*1e66f787SSean Bruno 883*1e66f787SSean Bruno typedef struct pqisrc_bmic_flush_cache { 884*1e66f787SSean Bruno uint8_t disable_cache; 885*1e66f787SSean Bruno uint8_t power_action; 886*1e66f787SSean Bruno uint8_t ndu_flush_cache; 887*1e66f787SSean Bruno uint8_t halt_event; 888*1e66f787SSean Bruno uint8_t reserved[28]; 889*1e66f787SSean Bruno } OS_ATTRIBUTE_PACKED pqisrc_bmic_flush_cache_t; 890*1e66f787SSean Bruno 891*1e66f787SSean Bruno /* for halt_event member of pqisrc_bmic_flush_cache_t */ 892*1e66f787SSean Bruno enum pqisrc_flush_cache_event_type { 893*1e66f787SSean Bruno PQISRC_NONE_CACHE_FLUSH_ONLY = 0, 894*1e66f787SSean Bruno PQISRC_SHUTDOWN = 1, 895*1e66f787SSean Bruno PQISRC_HIBERNATE = 2, 896*1e66f787SSean Bruno PQISRC_SUSPEND = 3, 897*1e66f787SSean Bruno PQISRC_RESTART = 4 898*1e66f787SSean Bruno }; 899*1e66f787SSean Bruno 900*1e66f787SSean Bruno struct pqisrc_softstate; 901*1e66f787SSean Bruno struct request_container_block; 902*1e66f787SSean Bruno typedef void (*success_callback)(struct pqisrc_softstate *, struct request_container_block *); 903*1e66f787SSean Bruno typedef void (*error_callback)(struct pqisrc_softstate *, struct request_container_block *, uint16_t); 904*1e66f787SSean Bruno 905*1e66f787SSean Bruno /* Request container block */ 906*1e66f787SSean Bruno typedef struct request_container_block { 907*1e66f787SSean Bruno void *req; 908*1e66f787SSean Bruno void *error_info; 909*1e66f787SSean Bruno REQUEST_STATUS_T status; 910*1e66f787SSean Bruno uint32_t tag; 911*1e66f787SSean Bruno sgt_t *sg_chain_virt; 912*1e66f787SSean Bruno dma_addr_t sg_chain_dma; 913*1e66f787SSean Bruno uint32_t data_dir; 914*1e66f787SSean Bruno pqi_scsi_dev_t *dvp; 915*1e66f787SSean Bruno struct pqisrc_softstate *softs; 916*1e66f787SSean Bruno success_callback success_cmp_callback; 917*1e66f787SSean Bruno error_callback error_cmp_callback; 918*1e66f787SSean Bruno uint8_t *cdbp; 919*1e66f787SSean Bruno int cmdlen; 920*1e66f787SSean Bruno uint32_t bcount; /* buffer size in byte */ 921*1e66f787SSean Bruno uint32_t ioaccel_handle; 922*1e66f787SSean Bruno boolean_t encrypt_enable; 923*1e66f787SSean Bruno struct pqi_enc_info enc_info; 924*1e66f787SSean Bruno int cm_flags; 925*1e66f787SSean Bruno void *cm_data; /* pointer to data in kernel space */ 926*1e66f787SSean Bruno bus_dmamap_t cm_datamap; 927*1e66f787SSean Bruno uint32_t nseg; 928*1e66f787SSean Bruno union ccb *cm_ccb; 929*1e66f787SSean Bruno sgt_t *sgt; /* sg table */ 930*1e66f787SSean Bruno int resp_qid; 931*1e66f787SSean Bruno boolean_t req_pending; 932*1e66f787SSean Bruno }rcb_t; 933*1e66f787SSean Bruno 934*1e66f787SSean Bruno typedef struct pqisrc_softstate { 935*1e66f787SSean Bruno OS_SPECIFIC_T os_specific; 936*1e66f787SSean Bruno struct ioa_registers *ioa_reg; 937*1e66f787SSean Bruno struct pqi_registers *pqi_reg; 938*1e66f787SSean Bruno char *pci_mem_base_vaddr; 939*1e66f787SSean Bruno PCI_ACC_HANDLE_T pci_mem_handle; 940*1e66f787SSean Bruno struct pqi_cap pqi_cap; 941*1e66f787SSean Bruno struct pqi_pref_settings pref_settings; 942*1e66f787SSean Bruno char fw_version[11]; 943*1e66f787SSean Bruno uint16_t fw_build_number; 944*1e66f787SSean Bruno uint32_t card; /* index to aac_cards */ 945*1e66f787SSean Bruno uint16_t vendid; /* vendor id */ 946*1e66f787SSean Bruno uint16_t subvendid; /* sub vendor id */ 947*1e66f787SSean Bruno uint16_t devid; /* device id */ 948*1e66f787SSean Bruno uint16_t subsysid; /* sub system id */ 949*1e66f787SSean Bruno controller_state_t ctlr_state; 950*1e66f787SSean Bruno struct dma_mem err_buf_dma_mem; 951*1e66f787SSean Bruno struct dma_mem admin_queue_dma_mem; 952*1e66f787SSean Bruno struct dma_mem op_ibq_dma_mem; 953*1e66f787SSean Bruno struct dma_mem op_obq_dma_mem; 954*1e66f787SSean Bruno struct dma_mem event_q_dma_mem; 955*1e66f787SSean Bruno struct dma_mem sg_dma_desc[PQISRC_MAX_OUTSTANDING_REQ]; 956*1e66f787SSean Bruno ib_queue_t admin_ib_queue; 957*1e66f787SSean Bruno ob_queue_t admin_ob_queue; 958*1e66f787SSean Bruno ob_queue_t event_q; 959*1e66f787SSean Bruno ob_queue_t op_ob_q[PQISRC_MAX_SUPPORTED_OP_OB_Q - 1];/* 1 event queue */ 960*1e66f787SSean Bruno ib_queue_t op_raid_ib_q[PQISRC_MAX_SUPPORTED_OP_RAID_IB_Q]; 961*1e66f787SSean Bruno ib_queue_t op_aio_ib_q[PQISRC_MAX_SUPPORTED_OP_AIO_IB_Q]; 962*1e66f787SSean Bruno uint32_t max_outstanding_io; 963*1e66f787SSean Bruno uint32_t max_io_for_scsi_ml; 964*1e66f787SSean Bruno uint32_t num_op_raid_ibq; 965*1e66f787SSean Bruno uint32_t num_op_aio_ibq; 966*1e66f787SSean Bruno uint32_t num_op_obq; 967*1e66f787SSean Bruno uint32_t num_elem_per_op_ibq; 968*1e66f787SSean Bruno uint32_t num_elem_per_op_obq; 969*1e66f787SSean Bruno uint32_t ibq_elem_size; 970*1e66f787SSean Bruno uint32_t obq_elem_size; 971*1e66f787SSean Bruno pqi_dev_cap_t pqi_dev_cap; 972*1e66f787SSean Bruno uint16_t max_ib_iu_length_per_fw; 973*1e66f787SSean Bruno uint16_t max_ib_iu_length; 974*1e66f787SSean Bruno unsigned max_sg_per_iu; 975*1e66f787SSean Bruno uint8_t ib_spanning_supported : 1; 976*1e66f787SSean Bruno uint8_t ob_spanning_supported : 1; 977*1e66f787SSean Bruno pqi_event_config_t event_config; 978*1e66f787SSean Bruno struct pqi_event pending_events[PQI_NUM_SUPPORTED_EVENTS]; 979*1e66f787SSean Bruno int intr_type; 980*1e66f787SSean Bruno int intr_count; 981*1e66f787SSean Bruno int num_cpus_online; 982*1e66f787SSean Bruno boolean_t share_opq_and_eventq; 983*1e66f787SSean Bruno rcb_t *rcb; 984*1e66f787SSean Bruno #ifndef LOCKFREE_STACK 985*1e66f787SSean Bruno pqi_taglist_t taglist; 986*1e66f787SSean Bruno #else 987*1e66f787SSean Bruno lockless_stack_t taglist; 988*1e66f787SSean Bruno #endif /* LOCKFREE_STACK */ 989*1e66f787SSean Bruno boolean_t devlist_lockcreated; 990*1e66f787SSean Bruno OS_LOCK_T devlist_lock OS_ATTRIBUTE_ALIGNED(8); 991*1e66f787SSean Bruno char devlist_lock_name[LOCKNAME_SIZE]; 992*1e66f787SSean Bruno pqi_scsi_dev_t *device_list[PQI_MAX_DEVICES][PQI_MAX_MULTILUN]; 993*1e66f787SSean Bruno OS_SEMA_LOCK_T scan_lock; 994*1e66f787SSean Bruno uint8_t lun_count[PQI_MAX_DEVICES]; 995*1e66f787SSean Bruno OS_ATOMIC64_T num_intrs; 996*1e66f787SSean Bruno uint64_t prev_num_intrs; 997*1e66f787SSean Bruno uint64_t prev_heartbeat_count; 998*1e66f787SSean Bruno uint64_t *heartbeat_counter_abs_addr; 999*1e66f787SSean Bruno uint64_t heartbeat_counter_off; 1000*1e66f787SSean Bruno uint64_t num_heartbeats_requested; 1001*1e66f787SSean Bruno uint32_t bus_id; 1002*1e66f787SSean Bruno uint32_t device_id; 1003*1e66f787SSean Bruno uint32_t func_id; 1004*1e66f787SSean Bruno char *os_name; 1005*1e66f787SSean Bruno boolean_t ctrl_online; 1006*1e66f787SSean Bruno uint8_t pqi_reset_quiesce_allowed : 1; 1007*1e66f787SSean Bruno boolean_t ctrl_in_pqi_mode; 1008*1e66f787SSean Bruno }pqisrc_softstate_t; 1009*1e66f787SSean Bruno 1010*1e66f787SSean Bruno #endif 1011