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 2024 Racktop Systems, Inc. 14 */ 15 #ifndef _LMRC_H 16 #define _LMRC_H 17 18 #include <sys/list.h> 19 #include <sys/types.h> 20 21 #include <sys/scsi/scsi.h> 22 #include <sys/scsi/adapters/mfi/mfi_pd.h> 23 24 #include <sys/taskq_impl.h> 25 26 #if !defined(_LITTLE_ENDIAN) || !defined(_BIT_FIELDS_LTOH) 27 #error "lmrc only works on little endian systems" 28 #endif 29 30 typedef enum lmrc_adapter_class lmrc_adapter_class_t; 31 typedef enum lmrc_init_level lmrc_init_level_t; 32 typedef struct lmrc_dma lmrc_dma_t; 33 typedef struct lmrc_mpt_cmd lmrc_mpt_cmd_t; 34 typedef struct lmrc_mfi_cmd lmrc_mfi_cmd_t; 35 typedef struct lmrc_scsa_cmd lmrc_scsa_cmd_t; 36 typedef struct lmrc_pd lmrc_pd_t; 37 typedef struct lmrc_tgt lmrc_tgt_t; 38 typedef struct lmrc lmrc_t; 39 40 #include "lmrc_reg.h" 41 #include "lmrc_phys.h" 42 43 extern void *lmrc_state; 44 45 enum lmrc_adapter_class { 46 LMRC_ACLASS_OTHER, 47 LMRC_ACLASS_GEN3, 48 LMRC_ACLASS_VENTURA, 49 LMRC_ACLASS_AERO, 50 }; 51 52 /* iports for RAID and physical targets */ 53 #define LMRC_IPORT_RAID "v0" 54 #define LMRC_IPORT_PHYS "p0" 55 56 /* in seconds */ 57 #define LMRC_IO_TIMEOUT 10 58 #define LMRC_RESET_TIMEOUT 180 59 #define LMRC_RESET_WAIT_TIME 3 60 #define LMRC_INTERNAL_CMD_WAIT_TIME 180 61 62 #define LMRC_MAX_RESET_TRIES 3 63 64 enum lmrc_init_level { 65 LMRC_INITLEVEL_BASIC = (1 << 0), 66 LMRC_INITLEVEL_THREAD = (1 << 1), 67 LMRC_INITLEVEL_FM = (1 << 2), 68 LMRC_INITLEVEL_REGS = (1 << 3), 69 LMRC_INITLEVEL_INTR = (1 << 4), 70 LMRC_INITLEVEL_SYNC = (1 << 5), 71 LMRC_INITLEVEL_HBA = (1 << 6), 72 LMRC_INITLEVEL_NODE = (1 << 7), 73 LMRC_INITLEVEL_TASKQ = (1 << 8), 74 LMRC_INITLEVEL_AEN = (1 << 9), 75 LMRC_INITLEVEL_MFICMDS = (1 << 10), 76 LMRC_INITLEVEL_MPTCMDS = (1 << 11), 77 LMRC_INITLEVEL_FW = (1 << 12), 78 LMRC_INITLEVEL_RAID = (1 << 13), 79 LMRC_INITLEVEL_PHYS = (1 << 14), 80 }; 81 82 #define INITLEVEL_SET(_lmrc, name) \ 83 do { \ 84 VERIFY(!((_lmrc)->l_init_level & (name))); \ 85 (_lmrc)->l_init_level |= (name); \ 86 } while (0) 87 88 #define INITLEVEL_CLEAR(_lmrc, name) \ 89 do { \ 90 VERIFY((_lmrc)->l_init_level & (name)); \ 91 (_lmrc)->l_init_level &= ~(name); \ 92 } while (0) 93 94 #define INITLEVEL_ACTIVE(_lmrc, name) \ 95 (((_lmrc)->l_init_level & (name)) != 0) 96 97 struct lmrc_dma { 98 ddi_dma_handle_t ld_hdl; 99 ddi_acc_handle_t ld_acc; 100 void *ld_buf; 101 size_t ld_len; 102 }; 103 104 typedef void (lmrc_mpt_cmd_cb_t)(lmrc_t *, lmrc_mpt_cmd_t *); 105 106 struct lmrc_mpt_cmd { 107 list_node_t mpt_node; 108 lmrc_dma_t mpt_chain_dma; 109 lmrc_dma_t mpt_sense_dma; 110 uint16_t mpt_smid; 111 uint16_t mpt_queue; 112 113 lmrc_mfi_cmd_t *mpt_mfi; 114 struct scsi_pkt *mpt_pkt; 115 116 void *mpt_io_frame; 117 Mpi25IeeeSgeChain64_t *mpt_chain; 118 uint8_t *mpt_sense; 119 120 kmutex_t mpt_lock; 121 kcondvar_t mpt_cv; 122 boolean_t mpt_complete; 123 hrtime_t mpt_timeout; 124 125 taskq_ent_t mpt_tqent; 126 127 lmrc_t *mpt_lmrc; 128 }; 129 130 typedef void (lmrc_mfi_cmd_cb_t)(lmrc_t *, lmrc_mfi_cmd_t *); 131 132 struct lmrc_mfi_cmd { 133 list_node_t mfi_node; 134 lmrc_dma_t mfi_frame_dma; 135 136 mfi_frame_t *mfi_frame; 137 uint32_t mfi_idx; 138 uint16_t mfi_smid; 139 140 kmutex_t mfi_lock; 141 kcondvar_t mfi_cv; 142 lmrc_dma_t mfi_data_dma; 143 144 lmrc_mfi_cmd_cb_t *mfi_callback; 145 taskq_ent_t mfi_tqent; 146 lmrc_mpt_cmd_t *mfi_mpt; 147 148 lmrc_t *mfi_lmrc; 149 }; 150 151 struct lmrc_scsa_cmd { 152 lmrc_mpt_cmd_t *sc_mpt; 153 lmrc_tgt_t *sc_tgt; 154 }; 155 156 struct lmrc_tgt { 157 krwlock_t tgt_lock; 158 kmutex_t tgt_mpt_active_lock; 159 list_t tgt_mpt_active; 160 lmrc_t *tgt_lmrc; 161 uint16_t tgt_dev_id; 162 uint8_t tgt_type; 163 uint8_t tgt_interconnect_type; 164 uint64_t tgt_wwn; 165 mfi_pd_info_t *tgt_pd_info; 166 char tgt_wwnstr[SCSI_WWN_BUFLEN]; 167 }; 168 169 struct lmrc { 170 dev_info_t *l_dip; 171 dev_info_t *l_raid_dip; 172 dev_info_t *l_phys_dip; 173 174 char l_iocname[16]; 175 176 lmrc_init_level_t l_init_level; 177 lmrc_adapter_class_t l_class; 178 179 kmutex_t l_mpt_cmd_lock; 180 list_t l_mpt_cmd_list; 181 lmrc_mpt_cmd_t **l_mpt_cmds; 182 183 kmutex_t l_mfi_cmd_lock; 184 list_t l_mfi_cmd_list; 185 lmrc_mfi_cmd_t **l_mfi_cmds; 186 187 lmrc_dma_t l_ioreq_dma; 188 lmrc_dma_t l_reply_dma; 189 190 ksema_t l_ioctl_sema; 191 192 kthread_t *l_thread; 193 kmutex_t l_thread_lock; 194 kcondvar_t l_thread_cv; 195 boolean_t l_thread_stop; 196 197 mfi_ctrl_info_t *l_ctrl_info; 198 199 ddi_intr_handle_t *l_intr_htable; 200 size_t l_intr_htable_size; 201 int l_intr_types; 202 int l_intr_type; 203 int l_intr_count; 204 uint_t l_intr_pri; 205 int l_intr_cap; 206 207 uint16_t *l_last_reply_idx; 208 uint32_t l_rphi[LMRC_MAX_REPLY_POST_HOST_INDEX]; 209 210 int l_fm_capabilities; 211 212 /* Controller HW/FW properties */ 213 boolean_t l_disable_online_ctrl_reset; 214 boolean_t l_fw_fault; 215 boolean_t l_fw_msix_enabled; 216 boolean_t l_fw_sync_cache_support; 217 size_t l_fw_supported_vd_count; 218 size_t l_fw_supported_pd_count; 219 220 boolean_t l_msix_combined; 221 boolean_t l_atomic_desc_support; 222 boolean_t l_64bit_dma_support; 223 boolean_t l_max_256_vd_support; 224 boolean_t l_use_seqnum_jbod_fp; 225 boolean_t l_pdmap_tgtid_support; 226 227 size_t l_max_reply_queues; 228 size_t l_max_num_sge; 229 size_t l_max_sge_in_main_msg; 230 size_t l_max_sge_in_chain; 231 232 uint32_t l_fw_outstanding_cmds; 233 uint32_t l_max_fw_cmds; 234 uint32_t l_max_scsi_cmds; 235 size_t l_reply_q_depth; 236 237 size_t l_reply_alloc_sz; 238 size_t l_io_frames_alloc_sz; 239 size_t l_max_chain_frame_sz; 240 size_t l_chain_offset_mfi_pthru; 241 size_t l_chain_offset_io_request; 242 243 size_t l_max_raid_map_sz; 244 size_t l_max_map_sz; 245 size_t l_current_map_sz; 246 247 size_t l_nvme_page_sz; 248 249 scsi_hba_tran_t *l_hba_tran; 250 dev_info_t *l_iport; 251 taskq_t *l_taskq; 252 253 ddi_dma_attr_t l_dma_attr; 254 ddi_dma_attr_t l_dma_attr_32; 255 ddi_device_acc_attr_t l_acc_attr; 256 caddr_t l_regmap; 257 ddi_acc_handle_t l_reghandle; 258 kmutex_t l_reg_lock; 259 260 krwlock_t l_raidmap_lock; 261 lmrc_fw_raid_map_t *l_raidmap; 262 263 krwlock_t l_pdmap_lock; 264 mfi_pd_map_t *l_pdmap; 265 266 lmrc_tgt_t l_targets[LMRC_MAX_LD + LMRC_MAX_PD]; 267 268 scsi_hba_tgtmap_t *l_raid_tgtmap; 269 scsi_hba_tgtmap_t *l_phys_tgtmap; 270 271 }; 272 273 int lmrc_check_acc_handle(ddi_acc_handle_t); 274 int lmrc_check_dma_handle(ddi_dma_handle_t); 275 276 void lmrc_dma_build_sgl(lmrc_t *, lmrc_mpt_cmd_t *, const ddi_dma_cookie_t *, 277 uint_t); 278 size_t lmrc_dma_get_size(lmrc_dma_t *); 279 void lmrc_dma_set_addr64(lmrc_dma_t *, uint64_t *); 280 void lmrc_dma_set_addr32(lmrc_dma_t *, uint32_t *); 281 int lmrc_dma_alloc(lmrc_t *, ddi_dma_attr_t, lmrc_dma_t *, size_t, uint64_t, 282 uint_t); 283 void lmrc_dma_free(lmrc_dma_t *); 284 285 void lmrc_disable_intr(lmrc_t *); 286 void lmrc_enable_intr(lmrc_t *); 287 uint_t lmrc_intr_ack(lmrc_t *); 288 289 void lmrc_send_atomic_request(lmrc_t *, lmrc_atomic_req_desc_t); 290 void lmrc_send_request(lmrc_t *, lmrc_req_desc_t); 291 lmrc_atomic_req_desc_t lmrc_build_atomic_request(lmrc_t *, lmrc_mpt_cmd_t *, 292 uint8_t); 293 294 void lmrc_fm_ereport(lmrc_t *, const char *); 295 296 int lmrc_hba_attach(lmrc_t *); 297 void lmrc_hba_detach(lmrc_t *); 298 299 void lmrc_thread(void *); 300 int lmrc_adapter_init(lmrc_t *); 301 int lmrc_ioc_init(lmrc_t *); 302 int lmrc_fw_init(lmrc_t *); 303 304 void lmrc_tgt_init(lmrc_tgt_t *, uint16_t, char *, mfi_pd_info_t *); 305 void lmrc_tgt_clear(lmrc_tgt_t *); 306 lmrc_tgt_t *lmrc_tgt_find(lmrc_t *, struct scsi_device *); 307 308 void lmrc_wakeup_mfi(lmrc_t *, lmrc_mfi_cmd_t *); 309 void lmrc_issue_mfi(lmrc_t *, lmrc_mfi_cmd_t *, lmrc_mfi_cmd_cb_t *); 310 int lmrc_wait_mfi(lmrc_t *, lmrc_mfi_cmd_t *, uint8_t); 311 int lmrc_issue_blocked_mfi(lmrc_t *, lmrc_mfi_cmd_t *); 312 313 int lmrc_poll_for_reply(lmrc_t *, lmrc_mpt_cmd_t *); 314 int lmrc_process_replies(lmrc_t *, uint8_t); 315 316 int lmrc_abort_mpt(lmrc_t *, lmrc_tgt_t *, lmrc_mpt_cmd_t *); 317 lmrc_mpt_cmd_t *lmrc_get_mpt(lmrc_t *); 318 void lmrc_put_mpt(lmrc_mpt_cmd_t *); 319 320 lmrc_mfi_cmd_t *lmrc_get_dcmd(lmrc_t *, uint16_t, uint32_t, uint32_t, uint_t); 321 void lmrc_put_dcmd(lmrc_t *, lmrc_mfi_cmd_t *); 322 323 lmrc_mfi_cmd_t *lmrc_get_mfi(lmrc_t *); 324 void lmrc_put_mfi(lmrc_mfi_cmd_t *); 325 int lmrc_abort_outstanding_mfi(lmrc_t *, const size_t); 326 int lmrc_build_mptmfi_passthru(lmrc_t *, lmrc_mfi_cmd_t *); 327 328 int lmrc_start_aen(lmrc_t *); 329 330 int lmrc_ctrl_shutdown(lmrc_t *); 331 332 /* 333 * per-target active MPT command list functions 334 */ 335 336 /* 337 * lmrc_tgt_first_active_mpt 338 * 339 * Returns the first active MPT command of a target. The MPT command is returned 340 * locked. 341 */ 342 static inline lmrc_mpt_cmd_t * 343 lmrc_tgt_first_active_mpt(lmrc_tgt_t *tgt) 344 { 345 lmrc_mpt_cmd_t *mpt = list_head(&tgt->tgt_mpt_active); 346 347 ASSERT(mutex_owned(&tgt->tgt_mpt_active_lock)); 348 349 if (mpt != NULL) 350 mutex_enter(&mpt->mpt_lock); 351 352 return (mpt); 353 } 354 355 /* 356 * lmrc_tgt_next_active_mpt 357 * 358 * Given a MPT command on the active list of a target, returns the next active 359 * MPT command on that target. The given MPT command is unlocked, and the next 360 * command is returned locked. 361 */ 362 static inline lmrc_mpt_cmd_t * 363 lmrc_tgt_next_active_mpt(lmrc_tgt_t *tgt, lmrc_mpt_cmd_t *mpt) 364 { 365 lmrc_mpt_cmd_t *nextmpt; 366 367 ASSERT(mutex_owned(&tgt->tgt_mpt_active_lock)); 368 369 nextmpt = list_next(&tgt->tgt_mpt_active, mpt); 370 mutex_exit(&mpt->mpt_lock); 371 372 if (nextmpt != NULL) 373 mutex_enter(&nextmpt->mpt_lock); 374 375 return (nextmpt); 376 } 377 378 /* 379 * lmrc_tgt_add_active_mpt 380 * 381 * Adds a MPT command to the active command list of a target. The command 382 * mutex must be held. There's no risk for a deadlock against the iterator 383 * functions. 384 */ 385 static inline void 386 lmrc_tgt_add_active_mpt(lmrc_tgt_t *tgt, lmrc_mpt_cmd_t *mpt) 387 { 388 ASSERT(mutex_owned(&mpt->mpt_lock)); 389 390 mutex_enter(&tgt->tgt_mpt_active_lock); 391 list_insert_head(&tgt->tgt_mpt_active, mpt); 392 mutex_exit(&tgt->tgt_mpt_active_lock); 393 } 394 395 /* 396 * lmrc_tgt_rem_active_mpt 397 * 398 * Removes a MPT command from the active command list of a target. The command 399 * must not be locked to avoid a deadlock with against the iterator functions. 400 */ 401 static inline void 402 lmrc_tgt_rem_active_mpt(lmrc_tgt_t *tgt, lmrc_mpt_cmd_t *mpt) 403 { 404 ASSERT(!mutex_owned(&mpt->mpt_lock)); 405 406 mutex_enter(&tgt->tgt_mpt_active_lock); 407 list_remove(&tgt->tgt_mpt_active, mpt); 408 mutex_exit(&tgt->tgt_mpt_active_lock); 409 } 410 411 /* 412 * Number of replies to be processed before the Reply Post Host register 413 * is updated. 414 */ 415 #define LMRC_THRESHOLD_REPLY_COUNT 50 416 417 #endif /* _LMRC_H */ 418