--- /dev/null	Mon Aug  5 17:31:37 2019
+++ new/usr/src/uts/common/io/scsi/adapters/smartpqi/smartpqi.h	Mon Aug  5 17:31:37 2019
@@ -0,0 +1,625 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2019 Nexenta Systems, Inc.
+ */
+
+#ifndef _SMARTPQI_H
+#define	_SMARTPQI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* ---- Standard header files. ---- */
+#include <sys/note.h>
+#include <sys/scsi/scsi.h>
+#include <sys/pci.h>
+#include <sys/file.h>
+#include <sys/policy.h>
+#include <sys/model.h>
+#include <sys/sysevent.h>
+#include <sys/sysevent/eventdefs.h>
+#include <sys/sysevent/dr.h>
+#include <sys/sata/sata_defs.h>
+#include <sys/sata/sata_hba.h>
+#include <sys/scsi/generic/sas.h>
+#include <sys/scsi/impl/scsi_sas.h>
+#include <sys/scsi/impl/scsi_reset_notify.h>
+#include <sys/sdt.h>
+#include <sys/mdi_impldefs.h>
+#include <sys/fs/dv_node.h>
+#include <sys/sysmacros.h>
+#include <sys/systm.h>
+#include <smartpqi_hw.h>
+
+/* ---- Hint for ddi_soft_state_init() on amount of structs to alloc ---- */
+#define	SMARTPQI_INITIAL_SOFT_SPACE	1
+
+#define	SMARTPQI_MOD_STRING	"smartpqi 20180525"
+
+/* ---- Handy constants ---- */
+#define	UNDEFINED				-1
+#define	MAX_NAME_PROP_SIZE			256
+#define	LUN_PROP				"lun"
+#define	LUN64_PROP				"lun64"
+#define	MDI_GUID				"wwn"
+#define	NDI_GUID				"guid"
+#define	TARGET_PROP				"target"
+#define	LUN_PROP				"lun"
+#define	COMPAT_PROP				"compatible"
+#define	NAME_DISK				"disk"
+#define	NAME_ENCLOSURE				"enclosure"
+
+#define	CMD_TIMEOUT_SCAN_SECS			10
+#define	SYNC_CMDS_TIMEOUT_SECS			5
+#define	IO_SPACE				1
+#define	PQI_MAXTGTS				256
+
+#define	PQI_MIN_MSIX_VECTORS			1
+#define	PQI_MAX_MSIX_VECTORS			16
+#define	PQI_DEFAULT_QUEUE_GROUP			0
+#define	PQI_MAX_QUEUE_GROUPS			PQI_MAX_MSIX_VECTORS
+#define	PQI_MIN_OPERATIONAL_QUEUE_ID		1
+/* ---- Size of structure scsi_arq_status without sense data. ---- */
+#define PQI_ARQ_STATUS_NOSENSE_LEN    (sizeof (struct scsi_arq_status) - \
+    sizeof (struct scsi_extended_sense))
+
+/* ---- macros to return various addresses ---- */
+#define	ADDR2TRAN(ap)	((ap)->a_hba_tran)
+#define	TRAN2PQI(hba)	((pqi_state_t)(hba)->tran_hba_private)
+#define	ADDR2PQI(ap)	(TRAN2PQI(ADDR2TRAN(ap)))
+#define	PKT2CMD(pkt)	((pqi_cmd_t)(pkt)->pkt_ha_private)
+#define	CMD2PKT(cmd)	((struct scsi_pkt *)(cmd)->pc_pkt)
+
+/* ---- PQI configuration ---- */
+#define	PQI_MAX_OUTSTANDING_REQUESTS		32
+#define	PQI_ERROR_BUFFER_ELEMENT_LENGTH sizeof (struct pqi_raid_error_info)
+#define	PQI_CREATE_ADMIN_QUEUE_PAIR		1
+#define	PQI_DELETE_ADMIN_QUEUE_PAIR		2
+#define	PQI_MAX_TRANSFER_SIZE			(4 * 1024U * 1024U)
+#define	PQI_MAX_RESET_XFER_SIZE			(512 * 1024)
+#define	PQI_NUM_SUPPORTED_EVENTS		7
+#define	PQI_RESERVED_IO_SLOTS_LUN_RESET		1
+#define	PQI_RESERVED_IO_SLOTS_EVENT_ACK	PQI_NUM_SUPPORTED_EVENTS
+#define	PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS	3
+#define	PQI_RESERVED_IO_SLOTS \
+	(PQI_RESERVED_IO_SLOTS_LUN_RESET + PQI_RESERVED_IO_SLOTS_EVENT_ACK + \
+	PQI_RESERVED_IO_SLOTS_SYNCHRONOUS_REQUESTS)
+#define	PQI_MAX_SCATTER_GATHER			0x200
+
+/* ---- SIS constants ---- */
+#define	SIS_BASE_STRUCT_ALIGNMENT		16
+
+/* ---- Once every 10 seconds ---- */
+#define	WATCHDOG (10 * MICROSEC)
+
+/* ---- Update HBA time of day clock once a day ---- */
+#define	MINUTE		60
+#define	HOUR		(60 * MINUTE)
+#define	DAY		(24 * HOUR)
+
+#define	HBA_IS_QUIESCED(s)	(((s)->s_flags & PQI_HBA_QUIESCED) != 0)
+#define	HBA_QUIESCED_PENDING(s)	\
+	(((s)->s_flags & PQI_HBA_QUIESCED_PENDING) != 0 && \
+	((s)->s_cmd_queue_len == 0))
+#define	PQIALIGN_TYPED(addr, align, type) \
+	(type)(((uintptr_t)(addr) + align - 1) & ~(align - 1))
+
+/* ---- Handy macros to get/set device registers ---- */
+#define	G8(state, __reg__) \
+    ddi_get8(state->s_datap, &state->s_reg->__reg__)
+#define	G16(state, __reg__) \
+    ddi_get16(state->s_datap, &state->s_reg->__reg__)
+#define	G32(state, __reg__) \
+    ddi_get32(state->s_datap, &state->s_reg->__reg__)
+#define	S8(state, __reg__, val) \
+    ddi_put8(state->s_datap, &state->s_reg->__reg__, val)
+#define	S32(state, __reg__, val) \
+    ddi_put32(state->s_datap, &state->s_reg->__reg__, val)
+#define	S64(state, __reg__, val) \
+    ddi_put64(state->s_datap, &state->s_reg->__reg__, val)
+#define	G64(state, __reg__) \
+    ddi_get64(state->s_datap, &state->s_reg->__reg__)
+
+/*
+ * Yuck! Internal knowledge of MPxIO, but since this variable is required
+ * to use MPxIO and there's no public API it must be declared here. Both
+ * the iSCSI Initiator and MPT SAS drivers do the same thing.
+ */
+extern dev_info_t *scsi_vhci_dip;
+
+typedef enum pqi_io_path {
+	RAID_PATH = 0,
+	AIO_PATH = 1
+} pqi_path_t;
+
+typedef struct dma_overhead {
+	ddi_dma_handle_t	handle;
+	ddi_acc_handle_t	acc;
+	caddr_t			alloc_memory;
+	size_t			len_to_alloc;
+	size_t			allocated_len;
+	uint64_t		dma_addr;
+	uint_t			cookie_count;
+	ddi_dma_cookie_t	second;
+} pqi_dma_overhead_t;
+
+typedef struct pqi_admin_queues {
+	caddr_t			iq_element_array;
+	caddr_t			oq_element_array;
+	volatile pqi_index_t	*iq_ci;
+	pqi_index_t		*oq_pi;
+	uint64_t		iq_element_array_bus_addr;
+	uint64_t		oq_element_array_bus_addr;
+	uint64_t		iq_ci_bus_addr;
+	uint64_t		oq_pi_bus_addr;
+	uint32_t		*iq_pi;
+	pqi_index_t		iq_pi_copy;
+	uint32_t		*oq_ci;
+	pqi_index_t		oq_ci_copy;
+	struct task_struct	*task;
+	uint16_t		int_msg_num;
+} pqi_admin_queues_t;
+
+typedef struct pqi_event_queue {
+	uint16_t		oq_id;
+	uint16_t		int_msg_num;
+	void			*oq_element_array;
+	pqi_index_t		*oq_pi;		/* In s_queue_dma space */
+	uint64_t		oq_element_array_bus_addr;
+	uint64_t		oq_pi_bus_addr;
+	uint32_t		*oq_ci;		/* In s_reg space */
+	pqi_index_t		oq_ci_copy;
+} pqi_event_queue_t;
+
+typedef struct pqi_queue_group {
+	struct pqi_state	*qg_softc;	/* backpointer */
+	uint16_t		iq_id[2];
+	uint16_t		oq_id;
+	uint16_t		int_msg_num;
+	caddr_t			iq_element_array[2];
+	caddr_t			oq_element_array;
+	uint64_t		iq_element_array_bus_addr[2];
+	uint64_t		oq_element_array_bus_addr;
+	pqi_index_t		iq_pi_copy[2];
+	pqi_index_t		oq_ci_copy;
+	/* ---- In s_reg space ---- */
+	uint32_t		*iq_pi[2];
+	uint32_t		*oq_ci;
+
+	/* ---- In s_queue_dma space ---- */
+	pqi_index_t		*iq_ci[2];
+	pqi_index_t		*oq_pi;
+
+	uint64_t		iq_ci_bus_addr[2];
+	uint64_t		oq_pi_bus_addr;
+
+	kmutex_t		submit_lock[2]; /* protect submission queue */
+	list_t			request_list[2];
+	int			submit_count;
+	int			cmplt_count;
+	boolean_t		qg_active;
+} pqi_queue_group_t;
+
+typedef struct pqi_io_request {
+	uint32_t		io_refcount;
+	uint16_t		io_index;
+	void			(*io_cb)(struct pqi_io_request *, void *);
+	void			*io_context;
+	uint8_t			io_raid_bypass : 1;
+	int			io_status;
+	pqi_queue_group_t	*io_queue_group;
+	struct pqi_cmd		*io_cmd;
+	void			*io_error_info;
+	pqi_dma_overhead_t	*io_sg_chain_dma;
+	void			*io_iu;
+	list_node_t		io_list_node;
+
+	/* ---- Debug aids ---- */
+	pqi_index_t		io_pi;
+	int			io_iu_type;
+
+	struct pqi_state	*io_softc;
+} pqi_io_request_t;
+
+typedef struct pqi_event {
+	boolean_t		ev_pending;
+	uint8_t			ev_type;
+	uint16_t		ev_id;
+	uint32_t		ev_additional;
+} *pqi_event_t;
+
+/* ---- Flags used in pqi_state ---- */
+#define	PQI_HBA_DRIVER_SHUTDOWN			0x0001
+#define	PQI_HBA_QUIESCED			0x0002
+#define	PQI_HBA_QUIESCED_PENDING		0x0004
+#define	PQI_HBA_AUTO_REQUEST_SENSE		0x0008
+#define	PQI_HBA_LUN_RESET_CAP			0x0010
+
+/* ---- Debug flags, example debug=0x10; in .conf file ---- */
+#define	DBG_LVL_CDB				0x0001
+#define	DBG_LVL_RQST				0x0002
+#define	DBG_LVL_STATE				0x0004
+#define	DBG_LVL_RAW_RQST			0x0008
+
+typedef struct pqi_state {
+	int			s_instance;
+	dev_info_t		*s_dip;
+	int			s_flags;
+	kmutex_t		s_mutex;
+	kmutex_t		s_intr_mutex;
+	kcondvar_t		s_quiescedvar;
+
+	/* ---- Used for serialized commands through driver ---- */
+	ksema_t			s_sync_rqst;
+	hrtime_t		s_sync_expire;
+	pqi_io_request_t	*s_sync_io;
+
+	int			s_intr_ready : 1,
+				s_offline : 1,
+				s_enable_mpxio : 1;
+	kmem_cache_t		*s_cmd_cache;
+	ddi_taskq_t		*s_events_taskq;
+	ddi_taskq_t		*s_complete_taskq;
+	timeout_id_t		s_time_of_day;
+	timeout_id_t		s_rescan;
+	timeout_id_t		s_cmd_timeout;
+
+	/* ---- Debug related state ---- */
+	int			s_debug_level;
+	list_t			s_mem_check;
+	kmutex_t		s_mem_mutex;
+	timeout_id_t		s_mem_timeo;
+
+	/* ---- State for watchdog ---- */
+	timeout_id_t		s_watchdog;
+	uint32_t		s_last_intr_count;
+	uint32_t		s_last_heartbeat_count;
+	uint32_t		s_intr_count;
+
+	/* ---- Interrupt related fields ---- */
+	int			s_intr_type;	/* Type of interrupt used */
+	int			s_intr_cnt;	/* # of interrupts */
+	uint_t			s_intr_pri;	/* Interrupt priority */
+	int			s_intr_cap;	/* Interrupt capabilities */
+	int			s_intr_size;	/* Size of s_htable */
+	ddi_intr_handle_t	*s_itable;	/* Interrupt table */
+
+	scsi_hba_tran_t		*s_tran;
+	ddi_dma_attr_t		s_msg_dma_attr;	/* Used for message frames */
+
+	/* ---- list of reset notification requests ---- */
+	struct scsi_reset_notify_entry	*s_reset_notify_listf;
+
+	pqi_ctrl_regs_t		*s_reg;
+	ddi_device_acc_attr_t	s_reg_acc_attr;
+	/* ---- operating regs data access handle ---- */
+	ddi_acc_handle_t	s_datap;
+
+	list_t			s_devnodes;
+	volatile uint32_t	s_cmd_queue_len;
+
+	/* ---- SIS capabilities from controller ---- */
+	uint32_t		s_max_sg_entries;
+	uint32_t		s_max_xfer_size;
+	uint32_t		s_max_outstanding_requests;
+	uint32_t		s_config_table_offset;
+	uint32_t		s_config_table_len;
+
+	/* ---- PQI capabilities from controller ---- */
+	uint32_t		*s_heartbeat_counter;
+	uint16_t		s_max_inbound_queues;
+	uint16_t		s_max_elements_per_iq;
+	uint16_t		s_max_iq_element_length;
+	uint16_t		s_max_outbound_queues;
+	uint16_t		s_max_elements_per_oq;
+	uint16_t		s_max_oq_element_length;
+	uint16_t		s_max_inbound_iu_length_per_firmware;
+	uint8_t			s_inbound_spanning_supported : 1,
+				s_outbound_spanning_supported:1,
+				s_pqi_mode_enabled : 1;
+	char			s_firmware_version[11];
+
+	/* ---- Computed values from config ---- */
+	uint32_t		s_max_sg_per_iu;
+	uint32_t		s_num_elements_per_iq;
+	uint32_t		s_num_elements_per_oq;
+	uint32_t		s_max_inbound_iu_length;
+	uint32_t		s_num_queue_groups;
+	uint32_t		s_max_io_slots;
+	uint32_t		s_sg_chain_buf_length;
+	uint32_t		s_max_sectors;
+
+	/* ---- allocation/free is protected by s_io_mutex ---- */
+	kmutex_t		s_io_mutex;
+	kcondvar_t		s_io_condvar;
+	pqi_io_request_t	*s_io_rqst_pool;
+	int			s_io_wait_cnt;
+	int			s_next_io_slot;
+	uint32_t		s_io_need;
+	uint32_t		s_io_had2wait;
+	uint32_t		s_io_sig;
+
+	pqi_dma_overhead_t	*s_error_dma;
+	pqi_dma_overhead_t	*s_adminq_dma;
+	pqi_admin_queues_t	s_admin_queues;
+	pqi_dma_overhead_t	*s_queue_dma;
+	pqi_queue_group_t	s_queue_groups[PQI_MAX_QUEUE_GROUPS];
+	pqi_event_queue_t	s_event_queue;
+	struct pqi_event	s_events[PQI_NUM_SUPPORTED_EVENTS];
+} *pqi_state_t;
+
+#define	RUN_MEM_CHECK	0
+#if RUN_MEM_CHECK == 1
+#define	MEM_CHECK_ON_DMA	1
+#define	MEM_CHECK_SIG		0xdeadcafe
+#define	PQI_ALLOC(len, flag) pqi_kmem_alloc(len, flag, __FILE__, __LINE__, s)
+#define	PQI_ZALLOC(len, flag) pqi_kmem_zalloc(len, flag, __FILE__, __LINE__, s)
+#define	PQI_FREE(v, len) pqi_kmem_free(v, len, s)
+#else
+#define	MEM_CHECK_ON_DMA	0
+#define	MEM_CHECK_SIG		0xdeadcafe
+#define	PQI_ALLOC(len, flag) kmem_alloc(len, flag)
+#define	PQI_ZALLOC(len, flag) kmem_zalloc(len, flag)
+#define	PQI_FREE(v, len) kmem_free(v, len)
+#endif
+
+typedef struct mem_check {
+	list_node_t		m_node;
+	uint32_t		m_sig;
+	int			m_line;
+	size_t			m_len;
+	char			m_file[80];
+} *mem_check_t;
+
+typedef struct pqi_device {
+	list_node_t		pd_list;
+	kmutex_t		pd_mutex;
+
+	/* ---- Protected by pd_mutex ---- */
+	list_t			pd_cmd_list;
+	int			pd_flags;
+
+	int			pd_active_cmds;
+	int			pd_target;
+
+	/* ---- Only one will be valid, MPxIO uses s_pip ---- */
+	dev_info_t		*pd_dip;
+	mdi_pathinfo_t		*pd_pip;
+	mdi_pathinfo_t		*pd_pip_offlined;
+
+	dev_info_t		*pd_parent;
+	int			pd_devtype;
+	int			pd_online : 1;
+	int			pd_scanned : 1;
+	int			pd_phys_dev : 1;
+	int			pd_external_raid : 1;
+	int			pd_aio_enabled : 1;
+	uint32_t		pd_aio_handle;
+	char			pd_scsi3addr[8];
+	uint64_t		pd_wwid;	/* big endian */
+	char			*pd_guid;
+	uint64_t		pd_sas_address;
+	uint8_t			pd_volume_id[16];
+	char			pd_vendor[8];	/* From INQUIRY */
+	char			pd_model[16];	/* From INQUIRY */
+} *pqi_device_t;
+
+/* ---- Flags used in pqi_cmd_t ---- */
+#define	PQI_FLAG_ABORTED	0x0001
+#define	PQI_FLAG_TIMED_OUT	0x0002
+#define	PQI_FLAG_RESET		0x0004
+#define	PQI_FLAG_IO_IOPB	0x0040
+#define	PQI_FLAG_DMA_VALID	0x0100
+#define	PQI_FLAG_CDB_EXT	0x0200
+#define	PQI_FLAG_SCB_EXT	0x0400
+#define	PQI_FLAG_PRIV_EXT	0x0800
+#define	PQI_FLAG_IO_READ	0x1000
+#define	PQI_FLAG_IO_BOUNCE	0x2000
+#define	PQI_FLAG_FINISHING	0x4000
+
+typedef enum pqi_cmd_state {
+	PQI_CMD_UNINIT		= 0,
+	PQI_CMD_CONSTRUCT,
+	PQI_CMD_INIT,
+	PQI_CMD_QUEUED,
+	PQI_CMD_STARTED,
+	PQI_CMD_CMPLT,
+	PQI_CMD_FATAL,
+	PQI_CMD_DESTRUCT
+} pqi_cmd_state_t;
+
+#define	PQI_FLAGS_PERSISTENT	\
+	(PQI_FLAG_DMA_VALID	|\
+	PQI_FLAG_IO_IOPB)
+
+#define	PQI_FLAGS_NON_HW_COMPLETION \
+	(PQI_FLAG_ABORTED	|\
+	PQI_FLAG_TIMED_OUT	|\
+	PQI_FLAG_RESET)
+
+typedef struct pqi_cmd {
+	list_node_t		pc_list;
+	pqi_cmd_state_t		pc_cmd_state;
+	pqi_cmd_state_t		pc_last_state;
+	struct scsi_pkt		*pc_pkt;
+	pqi_state_t		pc_softc;
+	pqi_device_t		pc_device;
+	int			pc_target;
+	ksema_t			*pc_poll;
+	uint8_t			pc_cdb[SCSI_CDB_SIZE];
+	struct scsi_arq_status	pc_cmd_scb;
+
+	uint64_t		pc_tgt_priv[2];
+	int			pc_dma_count;	/* bytes to transfer */
+
+	/*
+	 * Setting/clearing/testing of ABORT and FINISHING are
+	 * protected by pqi_device->pd_mutex. The other bits in
+	 * this flag are set during init_pkt and read only during
+	 * cleanup.
+	 */
+	int			pc_flags;
+
+	int			pc_tgtlen;
+	int			pc_statuslen;
+	int			pc_cmdlen;
+	hrtime_t		pc_expiration;
+	hrtime_t		pc_start_time;
+
+	/* ---- For partial DMA transfers ---- */
+	uint_t			pc_nwin;
+	uint_t			pc_winidx;
+	off_t			pc_dma_offset;
+	size_t			pc_dma_len;
+
+	/* ---- Valid after call to pqi_transport_command ---- */
+	pqi_io_request_t	*pc_io_rqst;
+
+	ddi_dma_handle_t	pc_dmahdl;
+	ddi_dma_cookie_t	pc_dmac;
+	uint_t			pc_dmaccount;	/* cookie count */
+	struct scsi_pkt		pc_cached_pkt;
+	ddi_dma_cookie_t	pc_cached_cookies[PQI_MAX_SCATTER_GATHER];
+} *pqi_cmd_t;
+
+/* ---- configuration table section IDs ---- */
+#define	PQI_CONFIG_TABLE_SECTION_GENERAL_INFO		0
+#define	PQI_CONFIG_TABLE_SECTION_FIRMWARE_FEATURES	1
+#define	PQI_CONFIG_TABLE_SECTION_FIRMWARE_ERRATA	2
+#define	PQI_CONFIG_TABLE_SECTION_DEBUG			3
+#define	PQI_CONFIG_TABLE_SECTION_HEARTBEAT		4
+
+/* ---- manifest constants for the flags field of pqi_sg_descriptor ---- */
+#define	CISS_SG_NORMAL				0x00000000
+#define	CISS_SG_LAST				0x40000000
+#define	CISS_SG_CHAIN				0x80000000
+
+/*
+ * According to the PQI spec, the IU header is only the first 4 bytes of our
+ * pqi_iu_header structure.
+ */
+#define	PQI_REQUEST_HEADER_LENGTH			4
+#define	PQI_REQUEST_IU_TASK_MANAGEMENT			0x13
+#define	PQI_REQUEST_IU_RAID_PATH_IO			0x14
+#define	PQI_REQUEST_IU_AIO_PATH_IO			0x15
+#define	PQI_REQUEST_IU_GENERAL_ADMIN			0x60
+#define	PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG	0x72
+#define	PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG		0x73
+#define	PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT		0xf6
+
+#define	MASKED_DEVICE(lunid)				((lunid)[3] & 0xc0)
+
+#define	MEMP(args...) (void) snprintf(m.mem + strlen(m.mem), \
+	m.len - strlen(m.mem), args)
+
+typedef struct mem_len_pair {
+	caddr_t	mem;
+	int	len;
+} mem_len_pair_t;
+
+/* ---- Defines for PQI mode ---- */
+#define	IRQ_MODE_NONE			0x00
+#define	VPD_PAGE			(1 << 8)
+
+/* ---- Defines for use in Legacy mode ---- */
+#define	SIS_CTRL_KERNEL_UP		0x080
+#define	SIS_CTRL_KERNEL_PANIC		0x100
+#define	SIS_MODE			0x0
+#define	PQI_MODE			0x1
+
+/* ---- smartpqi_main.c ---- */
+void *pqi_state;
+extern int pqi_do_scan;
+extern int pqi_do_ctrl;
+extern int pqi_do_offline;
+extern int pqi_offline_target;
+
+/* ---- smartpqi_intr.c ---- */
+int smartpqi_register_intrs(pqi_state_t);
+void smartpqi_unregister_intrs(pqi_state_t);
+void pqi_process_io_intr(pqi_state_t s, pqi_queue_group_t *qg);
+
+/* ---- smartpqi_sis.c ---- */
+boolean_t sis_reenable_mode(pqi_state_t s);
+void sis_write_scratch(pqi_state_t s, int mode);
+uint32_t sis_read_scratch(pqi_state_t s);
+boolean_t sis_wait_for_ctrl_ready(pqi_state_t s);
+boolean_t sis_get_ctrl_props(pqi_state_t s);
+boolean_t sis_init_base_struct_addr(pqi_state_t s);
+boolean_t sis_get_pqi_capabilities(pqi_state_t s);
+
+/* ---- smartpqi_init.c ---- */
+void pqi_free_io_resource(pqi_state_t s);
+boolean_t pqi_scsi_inquiry(pqi_state_t s, pqi_device_t dev, int vpd,
+    struct scsi_inquiry *inq, int len);
+void pqi_rescan_devices(pqi_state_t s);
+boolean_t pqi_check_firmware(pqi_state_t s);
+boolean_t pqi_prep_full(pqi_state_t s);
+
+/* ---- smartpqi_hba.c ---- */
+int smartpqi_register_hba(pqi_state_t);
+void smartpqi_unregister_hba(pqi_state_t);
+pqi_device_t pqi_find_target_dev(pqi_state_t s, int target);
+int pqi_cache_constructor(void *buf, void *un, int flags);
+void pqi_cache_destructor(void *buf, void *un);
+int pqi_config_all(dev_info_t *pdip, pqi_state_t s);
+void pqi_quiesced_notify(pqi_state_t s);
+
+/* ---- smartpqi_hw.c ---- */
+void pqi_start_io(pqi_state_t s, pqi_queue_group_t *qg, pqi_path_t path,
+    pqi_io_request_t *io);
+int pqi_transport_command(pqi_state_t s, pqi_cmd_t cmd);
+void pqi_fail_cmd(pqi_cmd_t cmd, uchar_t reason, uint_t stats);
+void pqi_fail_drive_cmds(pqi_device_t devp);
+void pqi_watchdog(void *v);
+void pqi_do_rescan(void *v);
+void pqi_event_worker(void *v);
+uint32_t pqi_disable_intr(pqi_state_t s);
+void pqi_enable_intr(pqi_state_t s, uint32_t old_state);
+boolean_t pqi_lun_reset(pqi_state_t s, pqi_device_t d);
+
+/* ---- smartpqi_util.c ---- */
+pqi_dma_overhead_t *pqi_alloc_single(pqi_state_t s, size_t len);
+void pqi_free_single(pqi_state_t s, pqi_dma_overhead_t *d);
+pqi_io_request_t *pqi_alloc_io(pqi_state_t s);
+void pqi_free_io(pqi_io_request_t *io);
+void pqi_dump_io(pqi_io_request_t *io);
+void pqi_cmd_sm(pqi_cmd_t cmd, pqi_cmd_state_t new_state, boolean_t grab_lock);
+char *pqi_event_to_str(uint8_t event);
+int pqi_map_event(uint8_t event);
+boolean_t pqi_supported_event(uint8_t event_type);
+char *bool_to_str(int v);
+char *dtype_to_str(int t);
+void pqi_free_mem_len(mem_len_pair_t *m);
+mem_len_pair_t pqi_alloc_mem_len(int len);
+mem_len_pair_t build_cdb_str(uint8_t *cdb);
+mem_len_pair_t mem_to_arraystr(uint8_t *ptr, size_t len);
+int pqi_is_offline(pqi_state_t s);
+void pqi_show_dev_state(pqi_state_t s);
+void *pqi_kmem_zalloc(size_t size, int kmflag, char *file, int line,
+    pqi_state_t s);
+void *pqi_kmem_alloc(size_t size, int kmflag, char *file, int line,
+    pqi_state_t s);
+void pqi_kmem_free(void *v, size_t, pqi_state_t s);
+void pqi_mem_check(void *v);
+char *cdb_to_str(uint8_t scsi_cmd);
+char *io_status_to_str(int val);
+char *scsi_status_to_str(uint8_t val);
+char *iu_type_to_str(int val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SMARTPQI_H */
