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 2019 Nexenta Systems, Inc.
  14  */
  15 
  16 #ifndef _SMARTPQI_H
  17 #define _SMARTPQI_H
  18 
  19 #ifdef __cplusplus
  20 extern "C" {
  21 #endif
  22 
  23 /* ---- Standard header files. ---- */
  24 #include <sys/note.h>
  25 #include <sys/scsi/scsi.h>
  26 #include <sys/pci.h>
  27 #include <sys/file.h>
  28 #include <sys/policy.h>
  29 #include <sys/model.h>
  30 #include <sys/sysevent.h>
  31 #include <sys/sysevent/eventdefs.h>
  32 #include <sys/sysevent/dr.h>
  33 #include <sys/sata/sata_defs.h>
  34 #include <sys/sata/sata_hba.h>
  35 #include <sys/scsi/generic/sas.h>
  36 #include <sys/scsi/impl/scsi_sas.h>
  37 #include <sys/scsi/impl/scsi_reset_notify.h>
  38 #include <sys/sdt.h>
  39 #include <sys/mdi_impldefs.h>
  40 #include <sys/fs/dv_node.h>
  41 #include <sys/sysmacros.h>
  42 #include <sys/systm.h>
  43 #include <smartpqi_hw.h>
  44 
  45 /* ---- Hint for ddi_soft_state_init() on amount of structs to alloc ---- */
  46 #define SMARTPQI_INITIAL_SOFT_SPACE     1
  47 
  48 #define SMARTPQI_MOD_STRING     "smartpqi 20180525"
  49 
  50 /* ---- Handy constants ---- */
  51 #define UNDEFINED                               -1
  52 #define MAX_NAME_PROP_SIZE                      256
  53 #define LUN_PROP                                "lun"
  54 #define LUN64_PROP                              "lun64"
  55 #define MDI_GUID                                "wwn"
  56 #define NDI_GUID                                "guid"
  57 #define TARGET_PROP                             "target"
  58 #define LUN_PROP                                "lun"
  59 #define COMPAT_PROP                             "compatible"
  60 #define NAME_DISK                               "disk"
  61 #define NAME_ENCLOSURE                          "enclosure"
  62 
  63 #define CMD_TIMEOUT_SCAN_SECS                   10
  64 #define SYNC_CMDS_TIMEOUT_SECS                  5
  65 #define IO_SPACE                                1
  66 #define PQI_MAXTGTS                             256
  67 
  68 #define PQI_MIN_MSIX_VECTORS                    1
  69 #define PQI_MAX_MSIX_VECTORS                    16
  70 #define PQI_DEFAULT_QUEUE_GROUP                 0
  71 #define PQI_MAX_QUEUE_GROUPS                    PQI_MAX_MSIX_VECTORS
  72 #define PQI_MIN_OPERATIONAL_QUEUE_ID            1
  73 /* ---- Size of structure scsi_arq_status without sense data. ---- */
  74 #define PQI_ARQ_STATUS_NOSENSE_LEN    (sizeof (struct scsi_arq_status) - \
  75     sizeof (struct scsi_extended_sense))
  76 
  77 /* ---- macros to return various addresses ---- */
  78 #define ADDR2TRAN(ap)   ((ap)->a_hba_tran)
  79 #define TRAN2PQI(hba)   ((pqi_state_t)(hba)->tran_hba_private)
  80 #define ADDR2PQI(ap)    (TRAN2PQI(ADDR2TRAN(ap)))
  81 #define PKT2CMD(pkt)    ((pqi_cmd_t)(pkt)->pkt_ha_private)
  82 #define CMD2PKT(cmd)    ((struct scsi_pkt *)(cmd)->pc_pkt)
  83 
  84 /* ---- PQI configuration ---- */
  85 #define PQI_MAX_OUTSTANDING_REQUESTS            32
  86 #define PQI_ERROR_BUFFER_ELEMENT_LENGTH sizeof (struct pqi_raid_error_info)
  87 #define PQI_CREATE_ADMIN_QUEUE_PAIR             1
  88 #define PQI_DELETE_ADMIN_QUEUE_PAIR             2
  89 #define PQI_MAX_TRANSFER_SIZE                   (4 * 1024U * 1024U)
  90 #define PQI_MAX_RESET_XFER_SIZE                 (512 * 1024)
  91 #define PQI_NUM_SUPPORTED_EVENTS                7
  92 #define PQI_RESERVED_IO_SLOTS_LUN_RESET         1
  93 #define PQI_RESERVED_IO_SLOTS_EVENT_ACK PQI_NUM_SUPPORTED_EVENTS
  94 #define PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS      3
  95 #define PQI_RESERVED_IO_SLOTS \
  96         (PQI_RESERVED_IO_SLOTS_LUN_RESET + PQI_RESERVED_IO_SLOTS_EVENT_ACK + \
  97         PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS)
  98 #define PQI_MAX_SCATTER_GATHER                  0x200
  99 
 100 /* ---- SIS constants ---- */
 101 #define SIS_BASE_STRUCT_ALIGNMENT               16
 102 
 103 /* ---- Once every 10 seconds ---- */
 104 #define WATCHDOG (10 * MICROSEC)
 105 
 106 /* ---- Update HBA time of day clock once a day ---- */
 107 #define MINUTE          60
 108 #define HOUR            (60 * MINUTE)
 109 #define DAY             (24 * HOUR)
 110 
 111 #define HBA_IS_QUIESCED(s)      (((s)->s_flags & PQI_HBA_QUIESCED) != 0)
 112 #define HBA_QUIESCED_PENDING(s) \
 113         (((s)->s_flags & PQI_HBA_QUIESCED_PENDING) != 0 && \
 114         ((s)->s_cmd_queue_len == 0))
 115 #define PQIALIGN_TYPED(addr, align, type) \
 116         (type)(((uintptr_t)(addr) + align - 1) & ~(align - 1))
 117 
 118 /* ---- Handy macros to get/set device registers ---- */
 119 #define G8(state, __reg__) \
 120     ddi_get8(state->s_datap, &state->s_reg->__reg__)
 121 #define G16(state, __reg__) \
 122     ddi_get16(state->s_datap, &state->s_reg->__reg__)
 123 #define G32(state, __reg__) \
 124     ddi_get32(state->s_datap, &state->s_reg->__reg__)
 125 #define S8(state, __reg__, val) \
 126     ddi_put8(state->s_datap, &state->s_reg->__reg__, val)
 127 #define S32(state, __reg__, val) \
 128     ddi_put32(state->s_datap, &state->s_reg->__reg__, val)
 129 #define S64(state, __reg__, val) \
 130     ddi_put64(state->s_datap, &state->s_reg->__reg__, val)
 131 #define G64(state, __reg__) \
 132     ddi_get64(state->s_datap, &state->s_reg->__reg__)
 133 
 134 /*
 135  * Yuck! Internal knowledge of MPxIO, but since this variable is required
 136  * to use MPxIO and there's no public API it must be declared here. Both
 137  * the iSCSI Initiator and MPT SAS drivers do the same thing.
 138  */
 139 extern dev_info_t *scsi_vhci_dip;
 140 
 141 typedef enum pqi_io_path {
 142         RAID_PATH = 0,
 143         AIO_PATH = 1
 144 } pqi_path_t;
 145 
 146 typedef struct dma_overhead {
 147         ddi_dma_handle_t        handle;
 148         ddi_acc_handle_t        acc;
 149         caddr_t                 alloc_memory;
 150         size_t                  len_to_alloc;
 151         size_t                  allocated_len;
 152         uint64_t                dma_addr;
 153         uint_t                  cookie_count;
 154         ddi_dma_cookie_t        second;
 155 } pqi_dma_overhead_t;
 156 
 157 typedef struct pqi_admin_queues {
 158         caddr_t                 iq_element_array;
 159         caddr_t                 oq_element_array;
 160         volatile pqi_index_t    *iq_ci;
 161         pqi_index_t             *oq_pi;
 162         uint64_t                iq_element_array_bus_addr;
 163         uint64_t                oq_element_array_bus_addr;
 164         uint64_t                iq_ci_bus_addr;
 165         uint64_t                oq_pi_bus_addr;
 166         uint32_t                *iq_pi;
 167         pqi_index_t             iq_pi_copy;
 168         uint32_t                *oq_ci;
 169         pqi_index_t             oq_ci_copy;
 170         struct task_struct      *task;
 171         uint16_t                int_msg_num;
 172 } pqi_admin_queues_t;
 173 
 174 typedef struct pqi_event_queue {
 175         uint16_t                oq_id;
 176         uint16_t                int_msg_num;
 177         void                    *oq_element_array;
 178         pqi_index_t             *oq_pi;         /* In s_queue_dma space */
 179         uint64_t                oq_element_array_bus_addr;
 180         uint64_t                oq_pi_bus_addr;
 181         uint32_t                *oq_ci;         /* In s_reg space */
 182         pqi_index_t             oq_ci_copy;
 183 } pqi_event_queue_t;
 184 
 185 typedef struct pqi_queue_group {
 186         struct pqi_state        *qg_softc;      /* backpointer */
 187         uint16_t                iq_id[2];
 188         uint16_t                oq_id;
 189         uint16_t                int_msg_num;
 190         caddr_t                 iq_element_array[2];
 191         caddr_t                 oq_element_array;
 192         uint64_t                iq_element_array_bus_addr[2];
 193         uint64_t                oq_element_array_bus_addr;
 194         pqi_index_t             iq_pi_copy[2];
 195         pqi_index_t             oq_ci_copy;
 196         /* ---- In s_reg space ---- */
 197         uint32_t                *iq_pi[2];
 198         uint32_t                *oq_ci;
 199 
 200         /* ---- In s_queue_dma space ---- */
 201         pqi_index_t             *iq_ci[2];
 202         pqi_index_t             *oq_pi;
 203 
 204         uint64_t                iq_ci_bus_addr[2];
 205         uint64_t                oq_pi_bus_addr;
 206 
 207         kmutex_t                submit_lock[2]; /* protect submission queue */
 208         list_t                  request_list[2];
 209         int                     submit_count;
 210         int                     cmplt_count;
 211         boolean_t               qg_active;
 212 } pqi_queue_group_t;
 213 
 214 typedef struct pqi_io_request {
 215         uint32_t                io_refcount;
 216         uint16_t                io_index;
 217         void                    (*io_cb)(struct pqi_io_request *, void *);
 218         void                    *io_context;
 219         uint8_t                 io_raid_bypass : 1;
 220         int                     io_status;
 221         pqi_queue_group_t       *io_queue_group;
 222         struct pqi_cmd          *io_cmd;
 223         void                    *io_error_info;
 224         pqi_dma_overhead_t      *io_sg_chain_dma;
 225         void                    *io_iu;
 226         list_node_t             io_list_node;
 227 
 228         /* ---- Debug aids ---- */
 229         pqi_index_t             io_pi;
 230         int                     io_iu_type;
 231 
 232         struct pqi_state        *io_softc;
 233 } pqi_io_request_t;
 234 
 235 typedef struct pqi_event {
 236         boolean_t               ev_pending;
 237         uint8_t                 ev_type;
 238         uint16_t                ev_id;
 239         uint32_t                ev_additional;
 240 } *pqi_event_t;
 241 
 242 /* ---- Flags used in pqi_state ---- */
 243 #define PQI_HBA_DRIVER_SHUTDOWN                 0x0001
 244 #define PQI_HBA_QUIESCED                        0x0002
 245 #define PQI_HBA_QUIESCED_PENDING                0x0004
 246 #define PQI_HBA_AUTO_REQUEST_SENSE              0x0008
 247 #define PQI_HBA_LUN_RESET_CAP                   0x0010
 248 
 249 /* ---- Debug flags, example debug=0x10; in .conf file ---- */
 250 #define DBG_LVL_CDB                             0x0001
 251 #define DBG_LVL_RQST                            0x0002
 252 #define DBG_LVL_STATE                           0x0004
 253 #define DBG_LVL_RAW_RQST                        0x0008
 254 
 255 typedef struct pqi_state {
 256         int                     s_instance;
 257         dev_info_t              *s_dip;
 258         int                     s_flags;
 259         kmutex_t                s_mutex;
 260         kmutex_t                s_intr_mutex;
 261         kcondvar_t              s_quiescedvar;
 262 
 263         /* ---- Used for serialized commands through driver ---- */
 264         ksema_t                 s_sync_rqst;
 265         hrtime_t                s_sync_expire;
 266         pqi_io_request_t        *s_sync_io;
 267 
 268         int                     s_intr_ready : 1,
 269                                 s_offline : 1,
 270                                 s_enable_mpxio : 1;
 271         kmem_cache_t            *s_cmd_cache;
 272         ddi_taskq_t             *s_events_taskq;
 273         ddi_taskq_t             *s_complete_taskq;
 274         timeout_id_t            s_time_of_day;
 275         timeout_id_t            s_rescan;
 276         timeout_id_t            s_cmd_timeout;
 277 
 278         /* ---- Debug related state ---- */
 279         int                     s_debug_level;
 280         list_t                  s_mem_check;
 281         kmutex_t                s_mem_mutex;
 282         timeout_id_t            s_mem_timeo;
 283 
 284         /* ---- State for watchdog ---- */
 285         timeout_id_t            s_watchdog;
 286         uint32_t                s_last_intr_count;
 287         uint32_t                s_last_heartbeat_count;
 288         uint32_t                s_intr_count;
 289 
 290         /* ---- Interrupt related fields ---- */
 291         int                     s_intr_type;    /* Type of interrupt used */
 292         int                     s_intr_cnt;     /* # of interrupts */
 293         uint_t                  s_intr_pri;     /* Interrupt priority */
 294         int                     s_intr_cap;     /* Interrupt capabilities */
 295         int                     s_intr_size;    /* Size of s_htable */
 296         ddi_intr_handle_t       *s_itable;      /* Interrupt table */
 297 
 298         scsi_hba_tran_t         *s_tran;
 299         ddi_dma_attr_t          s_msg_dma_attr; /* Used for message frames */
 300 
 301         /* ---- list of reset notification requests ---- */
 302         struct scsi_reset_notify_entry  *s_reset_notify_listf;
 303 
 304         pqi_ctrl_regs_t         *s_reg;
 305         ddi_device_acc_attr_t   s_reg_acc_attr;
 306         /* ---- operating regs data access handle ---- */
 307         ddi_acc_handle_t        s_datap;
 308 
 309         list_t                  s_devnodes;
 310         volatile uint32_t       s_cmd_queue_len;
 311 
 312         /* ---- SIS capabilities from controller ---- */
 313         uint32_t                s_max_sg_entries;
 314         uint32_t                s_max_xfer_size;
 315         uint32_t                s_max_outstanding_requests;
 316         uint32_t                s_config_table_offset;
 317         uint32_t                s_config_table_len;
 318 
 319         /* ---- PQI capabilities from controller ---- */
 320         uint32_t                *s_heartbeat_counter;
 321         uint16_t                s_max_inbound_queues;
 322         uint16_t                s_max_elements_per_iq;
 323         uint16_t                s_max_iq_element_length;
 324         uint16_t                s_max_outbound_queues;
 325         uint16_t                s_max_elements_per_oq;
 326         uint16_t                s_max_oq_element_length;
 327         uint16_t                s_max_inbound_iu_length_per_firmware;
 328         uint8_t                 s_inbound_spanning_supported : 1,
 329                                 s_outbound_spanning_supported:1,
 330                                 s_pqi_mode_enabled : 1;
 331         char                    s_firmware_version[11];
 332 
 333         /* ---- Computed values from config ---- */
 334         uint32_t                s_max_sg_per_iu;
 335         uint32_t                s_num_elements_per_iq;
 336         uint32_t                s_num_elements_per_oq;
 337         uint32_t                s_max_inbound_iu_length;
 338         uint32_t                s_num_queue_groups;
 339         uint32_t                s_max_io_slots;
 340         uint32_t                s_sg_chain_buf_length;
 341         uint32_t                s_max_sectors;
 342 
 343         /* ---- allocation/free is protected by s_io_mutex ---- */
 344         kmutex_t                s_io_mutex;
 345         kcondvar_t              s_io_condvar;
 346         pqi_io_request_t        *s_io_rqst_pool;
 347         int                     s_io_wait_cnt;
 348         int                     s_next_io_slot;
 349         uint32_t                s_io_need;
 350         uint32_t                s_io_had2wait;
 351         uint32_t                s_io_sig;
 352 
 353         pqi_dma_overhead_t      *s_error_dma;
 354         pqi_dma_overhead_t      *s_adminq_dma;
 355         pqi_admin_queues_t      s_admin_queues;
 356         pqi_dma_overhead_t      *s_queue_dma;
 357         pqi_queue_group_t       s_queue_groups[PQI_MAX_QUEUE_GROUPS];
 358         pqi_event_queue_t       s_event_queue;
 359         struct pqi_event        s_events[PQI_NUM_SUPPORTED_EVENTS];
 360 } *pqi_state_t;
 361 
 362 #define RUN_MEM_CHECK   0
 363 #if RUN_MEM_CHECK == 1
 364 #define MEM_CHECK_ON_DMA        1
 365 #define MEM_CHECK_SIG           0xdeadcafe
 366 #define PQI_ALLOC(len, flag) pqi_kmem_alloc(len, flag, __FILE__, __LINE__, s)
 367 #define PQI_ZALLOC(len, flag) pqi_kmem_zalloc(len, flag, __FILE__, __LINE__, s)
 368 #define PQI_FREE(v, len) pqi_kmem_free(v, len, s)
 369 #else
 370 #define MEM_CHECK_ON_DMA        0
 371 #define MEM_CHECK_SIG           0xdeadcafe
 372 #define PQI_ALLOC(len, flag) kmem_alloc(len, flag)
 373 #define PQI_ZALLOC(len, flag) kmem_zalloc(len, flag)
 374 #define PQI_FREE(v, len) kmem_free(v, len)
 375 #endif
 376 
 377 typedef struct mem_check {
 378         list_node_t             m_node;
 379         uint32_t                m_sig;
 380         int                     m_line;
 381         size_t                  m_len;
 382         char                    m_file[80];
 383 } *mem_check_t;
 384 
 385 typedef struct pqi_device {
 386         list_node_t             pd_list;
 387         kmutex_t                pd_mutex;
 388 
 389         /* ---- Protected by pd_mutex ---- */
 390         list_t                  pd_cmd_list;
 391         int                     pd_flags;
 392 
 393         int                     pd_active_cmds;
 394         int                     pd_target;
 395 
 396         /* ---- Only one will be valid, MPxIO uses s_pip ---- */
 397         dev_info_t              *pd_dip;
 398         mdi_pathinfo_t          *pd_pip;
 399         mdi_pathinfo_t          *pd_pip_offlined;
 400 
 401         dev_info_t              *pd_parent;
 402         int                     pd_devtype;
 403         int                     pd_online : 1;
 404         int                     pd_scanned : 1;
 405         int                     pd_phys_dev : 1;
 406         int                     pd_external_raid : 1;
 407         int                     pd_aio_enabled : 1;
 408         uint32_t                pd_aio_handle;
 409         char                    pd_scsi3addr[8];
 410         uint64_t                pd_wwid;        /* big endian */
 411         char                    *pd_guid;
 412         uint64_t                pd_sas_address;
 413         uint8_t                 pd_volume_id[16];
 414         char                    pd_vendor[8];   /* From INQUIRY */
 415         char                    pd_model[16];   /* From INQUIRY */
 416 } *pqi_device_t;
 417 
 418 /* ---- Flags used in pqi_cmd_t ---- */
 419 #define PQI_FLAG_ABORTED        0x0001
 420 #define PQI_FLAG_TIMED_OUT      0x0002
 421 #define PQI_FLAG_RESET          0x0004
 422 #define PQI_FLAG_IO_IOPB        0x0040
 423 #define PQI_FLAG_DMA_VALID      0x0100
 424 #define PQI_FLAG_CDB_EXT        0x0200
 425 #define PQI_FLAG_SCB_EXT        0x0400
 426 #define PQI_FLAG_PRIV_EXT       0x0800
 427 #define PQI_FLAG_IO_READ        0x1000
 428 #define PQI_FLAG_IO_BOUNCE      0x2000
 429 #define PQI_FLAG_FINISHING      0x4000
 430 
 431 typedef enum pqi_cmd_state {
 432         PQI_CMD_UNINIT          = 0,
 433         PQI_CMD_CONSTRUCT,
 434         PQI_CMD_INIT,
 435         PQI_CMD_QUEUED,
 436         PQI_CMD_STARTED,
 437         PQI_CMD_CMPLT,
 438         PQI_CMD_FATAL,
 439         PQI_CMD_DESTRUCT
 440 } pqi_cmd_state_t;
 441 
 442 #define PQI_FLAGS_PERSISTENT    \
 443         (PQI_FLAG_DMA_VALID     |\
 444         PQI_FLAG_IO_IOPB)
 445 
 446 #define PQI_FLAGS_NON_HW_COMPLETION \
 447         (PQI_FLAG_ABORTED       |\
 448         PQI_FLAG_TIMED_OUT      |\
 449         PQI_FLAG_RESET)
 450 
 451 typedef struct pqi_cmd {
 452         list_node_t             pc_list;
 453         pqi_cmd_state_t         pc_cmd_state;
 454         pqi_cmd_state_t         pc_last_state;
 455         struct scsi_pkt         *pc_pkt;
 456         pqi_state_t             pc_softc;
 457         pqi_device_t            pc_device;
 458         int                     pc_target;
 459         ksema_t                 *pc_poll;
 460         uint8_t                 pc_cdb[SCSI_CDB_SIZE];
 461         struct scsi_arq_status  pc_cmd_scb;
 462 
 463         uint64_t                pc_tgt_priv[2];
 464         int                     pc_dma_count;   /* bytes to transfer */
 465 
 466         /*
 467          * Setting/clearing/testing of ABORT and FINISHING are
 468          * protected by pqi_device->pd_mutex. The other bits in
 469          * this flag are set during init_pkt and read only during
 470          * cleanup.
 471          */
 472         int                     pc_flags;
 473 
 474         int                     pc_tgtlen;
 475         int                     pc_statuslen;
 476         int                     pc_cmdlen;
 477         hrtime_t                pc_expiration;
 478         hrtime_t                pc_start_time;
 479 
 480         /* ---- For partial DMA transfers ---- */
 481         uint_t                  pc_nwin;
 482         uint_t                  pc_winidx;
 483         off_t                   pc_dma_offset;
 484         size_t                  pc_dma_len;
 485 
 486         /* ---- Valid after call to pqi_transport_command ---- */
 487         pqi_io_request_t        *pc_io_rqst;
 488 
 489         ddi_dma_handle_t        pc_dmahdl;
 490         ddi_dma_cookie_t        pc_dmac;
 491         uint_t                  pc_dmaccount;   /* cookie count */
 492         struct scsi_pkt         pc_cached_pkt;
 493         ddi_dma_cookie_t        pc_cached_cookies[PQI_MAX_SCATTER_GATHER];
 494 } *pqi_cmd_t;
 495 
 496 /* ---- configuration table section IDs ---- */
 497 #define PQI_CONFIG_TABLE_SECTION_GENERAL_INFO           0
 498 #define PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES      1
 499 #define PQI_CONFIG_TABLE_SECTION_FIRMWARE_ERRATA        2
 500 #define PQI_CONFIG_TABLE_SECTION_DEBUG                  3
 501 #define PQI_CONFIG_TABLE_SECTION_HEARTBEAT              4
 502 
 503 /* ---- manifest constants for the flags field of pqi_sg_descriptor ---- */
 504 #define CISS_SG_NORMAL                          0x00000000
 505 #define CISS_SG_LAST                            0x40000000
 506 #define CISS_SG_CHAIN                           0x80000000
 507 
 508 /*
 509  * According to the PQI spec, the IU header is only the first 4 bytes of our
 510  * pqi_iu_header structure.
 511  */
 512 #define PQI_REQUEST_HEADER_LENGTH                       4
 513 #define PQI_REQUEST_IU_TASK_MANAGEMENT                  0x13
 514 #define PQI_REQUEST_IU_RAID_PATH_IO                     0x14
 515 #define PQI_REQUEST_IU_AIO_PATH_IO                      0x15
 516 #define PQI_REQUEST_IU_GENERAL_ADMIN                    0x60
 517 #define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG       0x72
 518 #define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG          0x73
 519 #define PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT         0xf6
 520 
 521 #define MASKED_DEVICE(lunid)                            ((lunid)[3] & 0xc0)
 522 
 523 #define MEMP(args...) (void) snprintf(m.mem + strlen(m.mem), \
 524         m.len - strlen(m.mem), args)
 525 
 526 typedef struct mem_len_pair {
 527         caddr_t mem;
 528         int     len;
 529 } mem_len_pair_t;
 530 
 531 /* ---- Defines for PQI mode ---- */
 532 #define IRQ_MODE_NONE                   0x00
 533 #define VPD_PAGE                        (1 << 8)
 534 
 535 /* ---- Defines for use in Legacy mode ---- */
 536 #define SIS_CTRL_KERNEL_UP              0x080
 537 #define SIS_CTRL_KERNEL_PANIC           0x100
 538 #define SIS_MODE                        0x0
 539 #define PQI_MODE                        0x1
 540 
 541 /* ---- smartpqi_main.c ---- */
 542 void *pqi_state;
 543 extern int pqi_do_scan;
 544 extern int pqi_do_ctrl;
 545 extern int pqi_do_offline;
 546 extern int pqi_offline_target;
 547 
 548 /* ---- smartpqi_intr.c ---- */
 549 int smartpqi_register_intrs(pqi_state_t);
 550 void smartpqi_unregister_intrs(pqi_state_t);
 551 void pqi_process_io_intr(pqi_state_t s, pqi_queue_group_t *qg);
 552 
 553 /* ---- smartpqi_sis.c ---- */
 554 boolean_t sis_reenable_mode(pqi_state_t s);
 555 void sis_write_scratch(pqi_state_t s, int mode);
 556 uint32_t sis_read_scratch(pqi_state_t s);
 557 boolean_t sis_wait_for_ctrl_ready(pqi_state_t s);
 558 boolean_t sis_get_ctrl_props(pqi_state_t s);
 559 boolean_t sis_init_base_struct_addr(pqi_state_t s);
 560 boolean_t sis_get_pqi_capabilities(pqi_state_t s);
 561 
 562 /* ---- smartpqi_init.c ---- */
 563 void pqi_free_io_resource(pqi_state_t s);
 564 boolean_t pqi_scsi_inquiry(pqi_state_t s, pqi_device_t dev, int vpd,
 565     struct scsi_inquiry *inq, int len);
 566 void pqi_rescan_devices(pqi_state_t s);
 567 boolean_t pqi_check_firmware(pqi_state_t s);
 568 boolean_t pqi_prep_full(pqi_state_t s);
 569 
 570 /* ---- smartpqi_hba.c ---- */
 571 int smartpqi_register_hba(pqi_state_t);
 572 void smartpqi_unregister_hba(pqi_state_t);
 573 pqi_device_t pqi_find_target_dev(pqi_state_t s, int target);
 574 int pqi_cache_constructor(void *buf, void *un, int flags);
 575 void pqi_cache_destructor(void *buf, void *un);
 576 int pqi_config_all(dev_info_t *pdip, pqi_state_t s);
 577 void pqi_quiesced_notify(pqi_state_t s);
 578 
 579 /* ---- smartpqi_hw.c ---- */
 580 void pqi_start_io(pqi_state_t s, pqi_queue_group_t *qg, pqi_path_t path,
 581     pqi_io_request_t *io);
 582 int pqi_transport_command(pqi_state_t s, pqi_cmd_t cmd);
 583 void pqi_fail_cmd(pqi_cmd_t cmd, uchar_t reason, uint_t stats);
 584 void pqi_fail_drive_cmds(pqi_device_t devp);
 585 void pqi_watchdog(void *v);
 586 void pqi_do_rescan(void *v);
 587 void pqi_event_worker(void *v);
 588 uint32_t pqi_disable_intr(pqi_state_t s);
 589 void pqi_enable_intr(pqi_state_t s, uint32_t old_state);
 590 boolean_t pqi_lun_reset(pqi_state_t s, pqi_device_t d);
 591 
 592 /* ---- smartpqi_util.c ---- */
 593 pqi_dma_overhead_t *pqi_alloc_single(pqi_state_t s, size_t len);
 594 void pqi_free_single(pqi_state_t s, pqi_dma_overhead_t *d);
 595 pqi_io_request_t *pqi_alloc_io(pqi_state_t s);
 596 void pqi_free_io(pqi_io_request_t *io);
 597 void pqi_dump_io(pqi_io_request_t *io);
 598 void pqi_cmd_sm(pqi_cmd_t cmd, pqi_cmd_state_t new_state, boolean_t grab_lock);
 599 char *pqi_event_to_str(uint8_t event);
 600 int pqi_map_event(uint8_t event);
 601 boolean_t pqi_supported_event(uint8_t event_type);
 602 char *bool_to_str(int v);
 603 char *dtype_to_str(int t);
 604 void pqi_free_mem_len(mem_len_pair_t *m);
 605 mem_len_pair_t pqi_alloc_mem_len(int len);
 606 mem_len_pair_t build_cdb_str(uint8_t *cdb);
 607 mem_len_pair_t mem_to_arraystr(uint8_t *ptr, size_t len);
 608 int pqi_is_offline(pqi_state_t s);
 609 void pqi_show_dev_state(pqi_state_t s);
 610 void *pqi_kmem_zalloc(size_t size, int kmflag, char *file, int line,
 611     pqi_state_t s);
 612 void *pqi_kmem_alloc(size_t size, int kmflag, char *file, int line,
 613     pqi_state_t s);
 614 void pqi_kmem_free(void *v, size_t, pqi_state_t s);
 615 void pqi_mem_check(void *v);
 616 char *cdb_to_str(uint8_t scsi_cmd);
 617 char *io_status_to_str(int val);
 618 char *scsi_status_to_str(uint8_t val);
 619 char *iu_type_to_str(int val);
 620 
 621 #ifdef __cplusplus
 622 }
 623 #endif
 624 
 625 #endif /* _SMARTPQI_H */