11e091e43SHans Rosenfeld /*
21e091e43SHans Rosenfeld * This file and its contents are supplied under the terms of the
31e091e43SHans Rosenfeld * Common Development and Distribution License ("CDDL"), version 1.0.
41e091e43SHans Rosenfeld * You may only use this file in accordance with the terms of version
51e091e43SHans Rosenfeld * 1.0 of the CDDL.
61e091e43SHans Rosenfeld *
71e091e43SHans Rosenfeld * A full copy of the text of the CDDL should have accompanied this
81e091e43SHans Rosenfeld * source. A copy of the CDDL is also available via the Internet at
91e091e43SHans Rosenfeld * http://www.illumos.org/license/CDDL.
101e091e43SHans Rosenfeld */
111e091e43SHans Rosenfeld
121e091e43SHans Rosenfeld /*
13d39213d9SHans Rosenfeld * Copyright 2024 Racktop Systems, Inc.
141e091e43SHans Rosenfeld */
151e091e43SHans Rosenfeld #ifndef _LMRC_H
161e091e43SHans Rosenfeld #define _LMRC_H
171e091e43SHans Rosenfeld
181e091e43SHans Rosenfeld #include <sys/list.h>
191e091e43SHans Rosenfeld #include <sys/types.h>
201e091e43SHans Rosenfeld
211e091e43SHans Rosenfeld #include <sys/scsi/scsi.h>
22*98f0a994SHans Rosenfeld #include <sys/scsi/adapters/mfi/mfi_pd.h>
23*98f0a994SHans Rosenfeld
241e091e43SHans Rosenfeld #include <sys/taskq_impl.h>
251e091e43SHans Rosenfeld
261e091e43SHans Rosenfeld #if !defined(_LITTLE_ENDIAN) || !defined(_BIT_FIELDS_LTOH)
271e091e43SHans Rosenfeld #error "lmrc only works on little endian systems"
281e091e43SHans Rosenfeld #endif
291e091e43SHans Rosenfeld
301e091e43SHans Rosenfeld typedef enum lmrc_adapter_class lmrc_adapter_class_t;
311e091e43SHans Rosenfeld typedef enum lmrc_init_level lmrc_init_level_t;
321e091e43SHans Rosenfeld typedef struct lmrc_dma lmrc_dma_t;
331e091e43SHans Rosenfeld typedef struct lmrc_mpt_cmd lmrc_mpt_cmd_t;
341e091e43SHans Rosenfeld typedef struct lmrc_mfi_cmd lmrc_mfi_cmd_t;
351e091e43SHans Rosenfeld typedef struct lmrc_scsa_cmd lmrc_scsa_cmd_t;
361e091e43SHans Rosenfeld typedef struct lmrc_pd lmrc_pd_t;
371e091e43SHans Rosenfeld typedef struct lmrc_tgt lmrc_tgt_t;
381e091e43SHans Rosenfeld typedef struct lmrc lmrc_t;
391e091e43SHans Rosenfeld
401e091e43SHans Rosenfeld #include "lmrc_reg.h"
411e091e43SHans Rosenfeld #include "lmrc_phys.h"
421e091e43SHans Rosenfeld
431e091e43SHans Rosenfeld extern void *lmrc_state;
441e091e43SHans Rosenfeld
451e091e43SHans Rosenfeld enum lmrc_adapter_class {
461e091e43SHans Rosenfeld LMRC_ACLASS_OTHER,
471e091e43SHans Rosenfeld LMRC_ACLASS_GEN3,
481e091e43SHans Rosenfeld LMRC_ACLASS_VENTURA,
491e091e43SHans Rosenfeld LMRC_ACLASS_AERO,
501e091e43SHans Rosenfeld };
511e091e43SHans Rosenfeld
521e091e43SHans Rosenfeld /* iports for RAID and physical targets */
531e091e43SHans Rosenfeld #define LMRC_IPORT_RAID "v0"
541e091e43SHans Rosenfeld #define LMRC_IPORT_PHYS "p0"
551e091e43SHans Rosenfeld
561e091e43SHans Rosenfeld /* in seconds */
571e091e43SHans Rosenfeld #define LMRC_IO_TIMEOUT 10
581e091e43SHans Rosenfeld #define LMRC_RESET_TIMEOUT 180
591e091e43SHans Rosenfeld #define LMRC_RESET_WAIT_TIME 3
601e091e43SHans Rosenfeld #define LMRC_INTERNAL_CMD_WAIT_TIME 180
611e091e43SHans Rosenfeld
621e091e43SHans Rosenfeld #define LMRC_MAX_RESET_TRIES 3
631e091e43SHans Rosenfeld
641e091e43SHans Rosenfeld enum lmrc_init_level {
651e091e43SHans Rosenfeld LMRC_INITLEVEL_BASIC = (1 << 0),
661e091e43SHans Rosenfeld LMRC_INITLEVEL_THREAD = (1 << 1),
671e091e43SHans Rosenfeld LMRC_INITLEVEL_FM = (1 << 2),
681e091e43SHans Rosenfeld LMRC_INITLEVEL_REGS = (1 << 3),
691e091e43SHans Rosenfeld LMRC_INITLEVEL_INTR = (1 << 4),
701e091e43SHans Rosenfeld LMRC_INITLEVEL_SYNC = (1 << 5),
711e091e43SHans Rosenfeld LMRC_INITLEVEL_HBA = (1 << 6),
721e091e43SHans Rosenfeld LMRC_INITLEVEL_NODE = (1 << 7),
731e091e43SHans Rosenfeld LMRC_INITLEVEL_TASKQ = (1 << 8),
741e091e43SHans Rosenfeld LMRC_INITLEVEL_AEN = (1 << 9),
751e091e43SHans Rosenfeld LMRC_INITLEVEL_MFICMDS = (1 << 10),
761e091e43SHans Rosenfeld LMRC_INITLEVEL_MPTCMDS = (1 << 11),
771e091e43SHans Rosenfeld LMRC_INITLEVEL_FW = (1 << 12),
78d39213d9SHans Rosenfeld LMRC_INITLEVEL_RAID = (1 << 13),
79d39213d9SHans Rosenfeld LMRC_INITLEVEL_PHYS = (1 << 14),
801e091e43SHans Rosenfeld };
811e091e43SHans Rosenfeld
821e091e43SHans Rosenfeld #define INITLEVEL_SET(_lmrc, name) \
831e091e43SHans Rosenfeld do { \
841e091e43SHans Rosenfeld VERIFY(!((_lmrc)->l_init_level & (name))); \
851e091e43SHans Rosenfeld (_lmrc)->l_init_level |= (name); \
861e091e43SHans Rosenfeld } while (0)
871e091e43SHans Rosenfeld
881e091e43SHans Rosenfeld #define INITLEVEL_CLEAR(_lmrc, name) \
891e091e43SHans Rosenfeld do { \
901e091e43SHans Rosenfeld VERIFY((_lmrc)->l_init_level & (name)); \
911e091e43SHans Rosenfeld (_lmrc)->l_init_level &= ~(name); \
921e091e43SHans Rosenfeld } while (0)
931e091e43SHans Rosenfeld
941e091e43SHans Rosenfeld #define INITLEVEL_ACTIVE(_lmrc, name) \
951e091e43SHans Rosenfeld (((_lmrc)->l_init_level & (name)) != 0)
961e091e43SHans Rosenfeld
971e091e43SHans Rosenfeld struct lmrc_dma {
981e091e43SHans Rosenfeld ddi_dma_handle_t ld_hdl;
991e091e43SHans Rosenfeld ddi_acc_handle_t ld_acc;
1001e091e43SHans Rosenfeld void *ld_buf;
1011e091e43SHans Rosenfeld size_t ld_len;
1021e091e43SHans Rosenfeld };
1031e091e43SHans Rosenfeld
1041e091e43SHans Rosenfeld typedef void (lmrc_mpt_cmd_cb_t)(lmrc_t *, lmrc_mpt_cmd_t *);
1051e091e43SHans Rosenfeld
1061e091e43SHans Rosenfeld struct lmrc_mpt_cmd {
1071e091e43SHans Rosenfeld list_node_t mpt_node;
1081e091e43SHans Rosenfeld lmrc_dma_t mpt_chain_dma;
1091e091e43SHans Rosenfeld lmrc_dma_t mpt_sense_dma;
1101e091e43SHans Rosenfeld uint16_t mpt_smid;
1111e091e43SHans Rosenfeld uint16_t mpt_queue;
1121e091e43SHans Rosenfeld
1131e091e43SHans Rosenfeld lmrc_mfi_cmd_t *mpt_mfi;
1141e091e43SHans Rosenfeld struct scsi_pkt *mpt_pkt;
1151e091e43SHans Rosenfeld
1161e091e43SHans Rosenfeld void *mpt_io_frame;
1171e091e43SHans Rosenfeld Mpi25IeeeSgeChain64_t *mpt_chain;
1181e091e43SHans Rosenfeld uint8_t *mpt_sense;
1191e091e43SHans Rosenfeld
1201e091e43SHans Rosenfeld kmutex_t mpt_lock;
1211e091e43SHans Rosenfeld kcondvar_t mpt_cv;
1221e091e43SHans Rosenfeld boolean_t mpt_complete;
1231e091e43SHans Rosenfeld hrtime_t mpt_timeout;
1241e091e43SHans Rosenfeld
1251e091e43SHans Rosenfeld taskq_ent_t mpt_tqent;
1261e091e43SHans Rosenfeld
1271e091e43SHans Rosenfeld lmrc_t *mpt_lmrc;
1281e091e43SHans Rosenfeld };
1291e091e43SHans Rosenfeld
1301e091e43SHans Rosenfeld typedef void (lmrc_mfi_cmd_cb_t)(lmrc_t *, lmrc_mfi_cmd_t *);
1311e091e43SHans Rosenfeld
1321e091e43SHans Rosenfeld struct lmrc_mfi_cmd {
1331e091e43SHans Rosenfeld list_node_t mfi_node;
1341e091e43SHans Rosenfeld lmrc_dma_t mfi_frame_dma;
1351e091e43SHans Rosenfeld
136*98f0a994SHans Rosenfeld mfi_frame_t *mfi_frame;
1371e091e43SHans Rosenfeld uint32_t mfi_idx;
1381e091e43SHans Rosenfeld uint16_t mfi_smid;
1391e091e43SHans Rosenfeld
1401e091e43SHans Rosenfeld kmutex_t mfi_lock;
1411e091e43SHans Rosenfeld kcondvar_t mfi_cv;
1421e091e43SHans Rosenfeld lmrc_dma_t mfi_data_dma;
1431e091e43SHans Rosenfeld
1441e091e43SHans Rosenfeld lmrc_mfi_cmd_cb_t *mfi_callback;
1451e091e43SHans Rosenfeld taskq_ent_t mfi_tqent;
1461e091e43SHans Rosenfeld lmrc_mpt_cmd_t *mfi_mpt;
1471e091e43SHans Rosenfeld
1481e091e43SHans Rosenfeld lmrc_t *mfi_lmrc;
1491e091e43SHans Rosenfeld };
1501e091e43SHans Rosenfeld
1511e091e43SHans Rosenfeld struct lmrc_scsa_cmd {
1521e091e43SHans Rosenfeld lmrc_mpt_cmd_t *sc_mpt;
1531e091e43SHans Rosenfeld lmrc_tgt_t *sc_tgt;
1541e091e43SHans Rosenfeld };
1551e091e43SHans Rosenfeld
1561e091e43SHans Rosenfeld struct lmrc_tgt {
1571e091e43SHans Rosenfeld krwlock_t tgt_lock;
1581e091e43SHans Rosenfeld kmutex_t tgt_mpt_active_lock;
1591e091e43SHans Rosenfeld list_t tgt_mpt_active;
1601e091e43SHans Rosenfeld lmrc_t *tgt_lmrc;
1611e091e43SHans Rosenfeld uint16_t tgt_dev_id;
1621e091e43SHans Rosenfeld uint8_t tgt_type;
1631e091e43SHans Rosenfeld uint8_t tgt_interconnect_type;
1641e091e43SHans Rosenfeld uint64_t tgt_wwn;
165*98f0a994SHans Rosenfeld mfi_pd_info_t *tgt_pd_info;
1661e091e43SHans Rosenfeld char tgt_wwnstr[SCSI_WWN_BUFLEN];
1671e091e43SHans Rosenfeld };
1681e091e43SHans Rosenfeld
1691e091e43SHans Rosenfeld struct lmrc {
1701e091e43SHans Rosenfeld dev_info_t *l_dip;
1711e091e43SHans Rosenfeld dev_info_t *l_raid_dip;
1721e091e43SHans Rosenfeld dev_info_t *l_phys_dip;
1731e091e43SHans Rosenfeld
1741e091e43SHans Rosenfeld char l_iocname[16];
1751e091e43SHans Rosenfeld
1761e091e43SHans Rosenfeld lmrc_init_level_t l_init_level;
1771e091e43SHans Rosenfeld lmrc_adapter_class_t l_class;
1781e091e43SHans Rosenfeld
1791e091e43SHans Rosenfeld kmutex_t l_mpt_cmd_lock;
1801e091e43SHans Rosenfeld list_t l_mpt_cmd_list;
1811e091e43SHans Rosenfeld lmrc_mpt_cmd_t **l_mpt_cmds;
1821e091e43SHans Rosenfeld
1831e091e43SHans Rosenfeld kmutex_t l_mfi_cmd_lock;
1841e091e43SHans Rosenfeld list_t l_mfi_cmd_list;
1851e091e43SHans Rosenfeld lmrc_mfi_cmd_t **l_mfi_cmds;
1861e091e43SHans Rosenfeld
1871e091e43SHans Rosenfeld lmrc_dma_t l_ioreq_dma;
1881e091e43SHans Rosenfeld lmrc_dma_t l_reply_dma;
1891e091e43SHans Rosenfeld
1901e091e43SHans Rosenfeld ksema_t l_ioctl_sema;
1911e091e43SHans Rosenfeld
1921e091e43SHans Rosenfeld kthread_t *l_thread;
1931e091e43SHans Rosenfeld kmutex_t l_thread_lock;
1941e091e43SHans Rosenfeld kcondvar_t l_thread_cv;
1951e091e43SHans Rosenfeld boolean_t l_thread_stop;
1961e091e43SHans Rosenfeld
197*98f0a994SHans Rosenfeld mfi_ctrl_info_t *l_ctrl_info;
1981e091e43SHans Rosenfeld
1991e091e43SHans Rosenfeld ddi_intr_handle_t *l_intr_htable;
2001e091e43SHans Rosenfeld size_t l_intr_htable_size;
2011e091e43SHans Rosenfeld int l_intr_types;
2021e091e43SHans Rosenfeld int l_intr_type;
2031e091e43SHans Rosenfeld int l_intr_count;
2041e091e43SHans Rosenfeld uint_t l_intr_pri;
2051e091e43SHans Rosenfeld int l_intr_cap;
2061e091e43SHans Rosenfeld
2071e091e43SHans Rosenfeld uint16_t *l_last_reply_idx;
2081e091e43SHans Rosenfeld uint32_t l_rphi[LMRC_MAX_REPLY_POST_HOST_INDEX];
2091e091e43SHans Rosenfeld
2101e091e43SHans Rosenfeld int l_fm_capabilities;
2111e091e43SHans Rosenfeld
2121e091e43SHans Rosenfeld /* Controller HW/FW properties */
2131e091e43SHans Rosenfeld boolean_t l_disable_online_ctrl_reset;
2141e091e43SHans Rosenfeld boolean_t l_fw_fault;
2151e091e43SHans Rosenfeld boolean_t l_fw_msix_enabled;
2161e091e43SHans Rosenfeld boolean_t l_fw_sync_cache_support;
2171e091e43SHans Rosenfeld size_t l_fw_supported_vd_count;
2181e091e43SHans Rosenfeld size_t l_fw_supported_pd_count;
2191e091e43SHans Rosenfeld
2201e091e43SHans Rosenfeld boolean_t l_msix_combined;
2211e091e43SHans Rosenfeld boolean_t l_atomic_desc_support;
2221e091e43SHans Rosenfeld boolean_t l_64bit_dma_support;
2231e091e43SHans Rosenfeld boolean_t l_max_256_vd_support;
2241e091e43SHans Rosenfeld boolean_t l_use_seqnum_jbod_fp;
2251e091e43SHans Rosenfeld boolean_t l_pdmap_tgtid_support;
2261e091e43SHans Rosenfeld
2271e091e43SHans Rosenfeld size_t l_max_reply_queues;
2281e091e43SHans Rosenfeld size_t l_max_num_sge;
2291e091e43SHans Rosenfeld size_t l_max_sge_in_main_msg;
2301e091e43SHans Rosenfeld size_t l_max_sge_in_chain;
2311e091e43SHans Rosenfeld
2321e091e43SHans Rosenfeld uint32_t l_fw_outstanding_cmds;
2331e091e43SHans Rosenfeld uint32_t l_max_fw_cmds;
2341e091e43SHans Rosenfeld uint32_t l_max_scsi_cmds;
2351e091e43SHans Rosenfeld size_t l_reply_q_depth;
2361e091e43SHans Rosenfeld
2371e091e43SHans Rosenfeld size_t l_reply_alloc_sz;
2381e091e43SHans Rosenfeld size_t l_io_frames_alloc_sz;
2391e091e43SHans Rosenfeld size_t l_max_chain_frame_sz;
2401e091e43SHans Rosenfeld size_t l_chain_offset_mfi_pthru;
2411e091e43SHans Rosenfeld size_t l_chain_offset_io_request;
2421e091e43SHans Rosenfeld
2431e091e43SHans Rosenfeld size_t l_max_raid_map_sz;
2441e091e43SHans Rosenfeld size_t l_max_map_sz;
2451e091e43SHans Rosenfeld size_t l_current_map_sz;
2461e091e43SHans Rosenfeld
2471e091e43SHans Rosenfeld size_t l_nvme_page_sz;
2481e091e43SHans Rosenfeld
2491e091e43SHans Rosenfeld scsi_hba_tran_t *l_hba_tran;
2501e091e43SHans Rosenfeld dev_info_t *l_iport;
2511e091e43SHans Rosenfeld taskq_t *l_taskq;
2521e091e43SHans Rosenfeld
2531e091e43SHans Rosenfeld ddi_dma_attr_t l_dma_attr;
2541e091e43SHans Rosenfeld ddi_dma_attr_t l_dma_attr_32;
2551e091e43SHans Rosenfeld ddi_device_acc_attr_t l_acc_attr;
2561e091e43SHans Rosenfeld caddr_t l_regmap;
2571e091e43SHans Rosenfeld ddi_acc_handle_t l_reghandle;
2581e091e43SHans Rosenfeld kmutex_t l_reg_lock;
2591e091e43SHans Rosenfeld
2601e091e43SHans Rosenfeld krwlock_t l_raidmap_lock;
2611e091e43SHans Rosenfeld lmrc_fw_raid_map_t *l_raidmap;
2621e091e43SHans Rosenfeld
2631e091e43SHans Rosenfeld krwlock_t l_pdmap_lock;
264*98f0a994SHans Rosenfeld mfi_pd_map_t *l_pdmap;
2651e091e43SHans Rosenfeld
2661e091e43SHans Rosenfeld lmrc_tgt_t l_targets[LMRC_MAX_LD + LMRC_MAX_PD];
2671e091e43SHans Rosenfeld
2681e091e43SHans Rosenfeld scsi_hba_tgtmap_t *l_raid_tgtmap;
2691e091e43SHans Rosenfeld scsi_hba_tgtmap_t *l_phys_tgtmap;
2701e091e43SHans Rosenfeld
2711e091e43SHans Rosenfeld };
2721e091e43SHans Rosenfeld
2731e091e43SHans Rosenfeld int lmrc_check_acc_handle(ddi_acc_handle_t);
2741e091e43SHans Rosenfeld int lmrc_check_dma_handle(ddi_dma_handle_t);
2751e091e43SHans Rosenfeld
2761e091e43SHans Rosenfeld void lmrc_dma_build_sgl(lmrc_t *, lmrc_mpt_cmd_t *, const ddi_dma_cookie_t *,
2771e091e43SHans Rosenfeld uint_t);
2781e091e43SHans Rosenfeld size_t lmrc_dma_get_size(lmrc_dma_t *);
2791e091e43SHans Rosenfeld void lmrc_dma_set_addr64(lmrc_dma_t *, uint64_t *);
2801e091e43SHans Rosenfeld void lmrc_dma_set_addr32(lmrc_dma_t *, uint32_t *);
2811e091e43SHans Rosenfeld int lmrc_dma_alloc(lmrc_t *, ddi_dma_attr_t, lmrc_dma_t *, size_t, uint64_t,
2821e091e43SHans Rosenfeld uint_t);
2831e091e43SHans Rosenfeld void lmrc_dma_free(lmrc_dma_t *);
2841e091e43SHans Rosenfeld
2851e091e43SHans Rosenfeld void lmrc_disable_intr(lmrc_t *);
2861e091e43SHans Rosenfeld void lmrc_enable_intr(lmrc_t *);
2871e091e43SHans Rosenfeld uint_t lmrc_intr_ack(lmrc_t *);
2881e091e43SHans Rosenfeld
2891e091e43SHans Rosenfeld void lmrc_send_atomic_request(lmrc_t *, lmrc_atomic_req_desc_t);
2901e091e43SHans Rosenfeld void lmrc_send_request(lmrc_t *, lmrc_req_desc_t);
2911e091e43SHans Rosenfeld lmrc_atomic_req_desc_t lmrc_build_atomic_request(lmrc_t *, lmrc_mpt_cmd_t *,
2921e091e43SHans Rosenfeld uint8_t);
2931e091e43SHans Rosenfeld
2941e091e43SHans Rosenfeld void lmrc_fm_ereport(lmrc_t *, const char *);
2951e091e43SHans Rosenfeld
2961e091e43SHans Rosenfeld int lmrc_hba_attach(lmrc_t *);
2971e091e43SHans Rosenfeld void lmrc_hba_detach(lmrc_t *);
2981e091e43SHans Rosenfeld
2991e091e43SHans Rosenfeld void lmrc_thread(void *);
3001e091e43SHans Rosenfeld int lmrc_adapter_init(lmrc_t *);
3011e091e43SHans Rosenfeld int lmrc_ioc_init(lmrc_t *);
3021e091e43SHans Rosenfeld int lmrc_fw_init(lmrc_t *);
3031e091e43SHans Rosenfeld
304*98f0a994SHans Rosenfeld void lmrc_tgt_init(lmrc_tgt_t *, uint16_t, char *, mfi_pd_info_t *);
3051e091e43SHans Rosenfeld void lmrc_tgt_clear(lmrc_tgt_t *);
3061e091e43SHans Rosenfeld lmrc_tgt_t *lmrc_tgt_find(lmrc_t *, struct scsi_device *);
3071e091e43SHans Rosenfeld
3081e091e43SHans Rosenfeld void lmrc_wakeup_mfi(lmrc_t *, lmrc_mfi_cmd_t *);
3091e091e43SHans Rosenfeld void lmrc_issue_mfi(lmrc_t *, lmrc_mfi_cmd_t *, lmrc_mfi_cmd_cb_t *);
3101e091e43SHans Rosenfeld int lmrc_wait_mfi(lmrc_t *, lmrc_mfi_cmd_t *, uint8_t);
3111e091e43SHans Rosenfeld int lmrc_issue_blocked_mfi(lmrc_t *, lmrc_mfi_cmd_t *);
3121e091e43SHans Rosenfeld
3131e091e43SHans Rosenfeld int lmrc_poll_for_reply(lmrc_t *, lmrc_mpt_cmd_t *);
3141e091e43SHans Rosenfeld int lmrc_process_replies(lmrc_t *, uint8_t);
3151e091e43SHans Rosenfeld
3161e091e43SHans Rosenfeld int lmrc_abort_mpt(lmrc_t *, lmrc_tgt_t *, lmrc_mpt_cmd_t *);
3171e091e43SHans Rosenfeld lmrc_mpt_cmd_t *lmrc_get_mpt(lmrc_t *);
3181e091e43SHans Rosenfeld void lmrc_put_mpt(lmrc_mpt_cmd_t *);
3191e091e43SHans Rosenfeld
3201e091e43SHans Rosenfeld lmrc_mfi_cmd_t *lmrc_get_dcmd(lmrc_t *, uint16_t, uint32_t, uint32_t, uint_t);
3211e091e43SHans Rosenfeld void lmrc_put_dcmd(lmrc_t *, lmrc_mfi_cmd_t *);
3221e091e43SHans Rosenfeld
3231e091e43SHans Rosenfeld lmrc_mfi_cmd_t *lmrc_get_mfi(lmrc_t *);
3241e091e43SHans Rosenfeld void lmrc_put_mfi(lmrc_mfi_cmd_t *);
3251e091e43SHans Rosenfeld int lmrc_abort_outstanding_mfi(lmrc_t *, const size_t);
326d8b83e34SHans Rosenfeld int lmrc_build_mptmfi_passthru(lmrc_t *, lmrc_mfi_cmd_t *);
3271e091e43SHans Rosenfeld
3281e091e43SHans Rosenfeld int lmrc_start_aen(lmrc_t *);
3291e091e43SHans Rosenfeld
3301e091e43SHans Rosenfeld int lmrc_ctrl_shutdown(lmrc_t *);
3311e091e43SHans Rosenfeld
3321e091e43SHans Rosenfeld /*
3331e091e43SHans Rosenfeld * per-target active MPT command list functions
3341e091e43SHans Rosenfeld */
3351e091e43SHans Rosenfeld
3361e091e43SHans Rosenfeld /*
3371e091e43SHans Rosenfeld * lmrc_tgt_first_active_mpt
3381e091e43SHans Rosenfeld *
3391e091e43SHans Rosenfeld * Returns the first active MPT command of a target. The MPT command is returned
3401e091e43SHans Rosenfeld * locked.
3411e091e43SHans Rosenfeld */
3421e091e43SHans Rosenfeld static inline lmrc_mpt_cmd_t *
lmrc_tgt_first_active_mpt(lmrc_tgt_t * tgt)3431e091e43SHans Rosenfeld lmrc_tgt_first_active_mpt(lmrc_tgt_t *tgt)
3441e091e43SHans Rosenfeld {
3451e091e43SHans Rosenfeld lmrc_mpt_cmd_t *mpt = list_head(&tgt->tgt_mpt_active);
3461e091e43SHans Rosenfeld
3471e091e43SHans Rosenfeld ASSERT(mutex_owned(&tgt->tgt_mpt_active_lock));
3481e091e43SHans Rosenfeld
3491e091e43SHans Rosenfeld if (mpt != NULL)
3501e091e43SHans Rosenfeld mutex_enter(&mpt->mpt_lock);
3511e091e43SHans Rosenfeld
3521e091e43SHans Rosenfeld return (mpt);
3531e091e43SHans Rosenfeld }
3541e091e43SHans Rosenfeld
3551e091e43SHans Rosenfeld /*
3561e091e43SHans Rosenfeld * lmrc_tgt_next_active_mpt
3571e091e43SHans Rosenfeld *
3581e091e43SHans Rosenfeld * Given a MPT command on the active list of a target, returns the next active
3591e091e43SHans Rosenfeld * MPT command on that target. The given MPT command is unlocked, and the next
3601e091e43SHans Rosenfeld * command is returned locked.
3611e091e43SHans Rosenfeld */
3621e091e43SHans Rosenfeld static inline lmrc_mpt_cmd_t *
lmrc_tgt_next_active_mpt(lmrc_tgt_t * tgt,lmrc_mpt_cmd_t * mpt)3631e091e43SHans Rosenfeld lmrc_tgt_next_active_mpt(lmrc_tgt_t *tgt, lmrc_mpt_cmd_t *mpt)
3641e091e43SHans Rosenfeld {
3651e091e43SHans Rosenfeld lmrc_mpt_cmd_t *nextmpt;
3661e091e43SHans Rosenfeld
3671e091e43SHans Rosenfeld ASSERT(mutex_owned(&tgt->tgt_mpt_active_lock));
3681e091e43SHans Rosenfeld
3691e091e43SHans Rosenfeld nextmpt = list_next(&tgt->tgt_mpt_active, mpt);
3701e091e43SHans Rosenfeld mutex_exit(&mpt->mpt_lock);
3711e091e43SHans Rosenfeld
3721e091e43SHans Rosenfeld if (nextmpt != NULL)
3731e091e43SHans Rosenfeld mutex_enter(&nextmpt->mpt_lock);
3741e091e43SHans Rosenfeld
3751e091e43SHans Rosenfeld return (nextmpt);
3761e091e43SHans Rosenfeld }
3771e091e43SHans Rosenfeld
3781e091e43SHans Rosenfeld /*
3791e091e43SHans Rosenfeld * lmrc_tgt_add_active_mpt
3801e091e43SHans Rosenfeld *
3811e091e43SHans Rosenfeld * Adds a MPT command to the active command list of a target. The command
3821e091e43SHans Rosenfeld * mutex must be held. There's no risk for a deadlock against the iterator
3831e091e43SHans Rosenfeld * functions.
3841e091e43SHans Rosenfeld */
3851e091e43SHans Rosenfeld static inline void
lmrc_tgt_add_active_mpt(lmrc_tgt_t * tgt,lmrc_mpt_cmd_t * mpt)3861e091e43SHans Rosenfeld lmrc_tgt_add_active_mpt(lmrc_tgt_t *tgt, lmrc_mpt_cmd_t *mpt)
3871e091e43SHans Rosenfeld {
3881e091e43SHans Rosenfeld ASSERT(mutex_owned(&mpt->mpt_lock));
3891e091e43SHans Rosenfeld
3901e091e43SHans Rosenfeld mutex_enter(&tgt->tgt_mpt_active_lock);
3911e091e43SHans Rosenfeld list_insert_head(&tgt->tgt_mpt_active, mpt);
3921e091e43SHans Rosenfeld mutex_exit(&tgt->tgt_mpt_active_lock);
3931e091e43SHans Rosenfeld }
3941e091e43SHans Rosenfeld
3951e091e43SHans Rosenfeld /*
3961e091e43SHans Rosenfeld * lmrc_tgt_rem_active_mpt
3971e091e43SHans Rosenfeld *
3981e091e43SHans Rosenfeld * Removes a MPT command from the active command list of a target. The command
3991e091e43SHans Rosenfeld * must not be locked to avoid a deadlock with against the iterator functions.
4001e091e43SHans Rosenfeld */
4011e091e43SHans Rosenfeld static inline void
lmrc_tgt_rem_active_mpt(lmrc_tgt_t * tgt,lmrc_mpt_cmd_t * mpt)4021e091e43SHans Rosenfeld lmrc_tgt_rem_active_mpt(lmrc_tgt_t *tgt, lmrc_mpt_cmd_t *mpt)
4031e091e43SHans Rosenfeld {
4041e091e43SHans Rosenfeld ASSERT(!mutex_owned(&mpt->mpt_lock));
4051e091e43SHans Rosenfeld
4061e091e43SHans Rosenfeld mutex_enter(&tgt->tgt_mpt_active_lock);
4071e091e43SHans Rosenfeld list_remove(&tgt->tgt_mpt_active, mpt);
4081e091e43SHans Rosenfeld mutex_exit(&tgt->tgt_mpt_active_lock);
4091e091e43SHans Rosenfeld }
4101e091e43SHans Rosenfeld
4111e091e43SHans Rosenfeld /*
4121e091e43SHans Rosenfeld * Number of replies to be processed before the Reply Post Host register
4131e091e43SHans Rosenfeld * is updated.
4141e091e43SHans Rosenfeld */
4151e091e43SHans Rosenfeld #define LMRC_THRESHOLD_REPLY_COUNT 50
4161e091e43SHans Rosenfeld
4171e091e43SHans Rosenfeld #endif /* _LMRC_H */
418