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 *
lmrc_tgt_first_active_mpt(lmrc_tgt_t * tgt)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 *
lmrc_tgt_next_active_mpt(lmrc_tgt_t * tgt,lmrc_mpt_cmd_t * mpt)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
lmrc_tgt_add_active_mpt(lmrc_tgt_t * tgt,lmrc_mpt_cmd_t * mpt)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
lmrc_tgt_rem_active_mpt(lmrc_tgt_t * tgt,lmrc_mpt_cmd_t * mpt)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