1 /*- 2 * Copyright (c) 2017 Broadcom. All rights reserved. 3 * The term "Broadcom" refers to Broadcom Limited and/or its subsidiaries. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * $FreeBSD$ 32 */ 33 34 /** 35 * @file 36 * 37 */ 38 39 #ifndef __OCS_UTILS_H 40 #define __OCS_UTILS_H 41 42 #include "ocs_list.h" 43 typedef struct ocs_array_s ocs_array_t; 44 45 extern void ocs_array_set_slablen(uint32_t len); 46 extern ocs_array_t *ocs_array_alloc(ocs_os_handle_t os, uint32_t size, uint32_t count); 47 extern void ocs_array_free(ocs_array_t *array); 48 extern void *ocs_array_get(ocs_array_t *array, uint32_t idx); 49 extern uint32_t ocs_array_get_count(ocs_array_t *array); 50 extern uint32_t ocs_array_get_size(ocs_array_t *array); 51 52 /* Void pointer array and iterator */ 53 typedef struct ocs_varray_s ocs_varray_t; 54 55 extern ocs_varray_t *ocs_varray_alloc(ocs_os_handle_t os, uint32_t entry_count); 56 extern void ocs_varray_free(ocs_varray_t *ai); 57 extern int32_t ocs_varray_add(ocs_varray_t *ai, void *entry); 58 extern void ocs_varray_iter_reset(ocs_varray_t *ai); 59 extern void *ocs_varray_iter_next(ocs_varray_t *ai); 60 extern void *_ocs_varray_iter_next(ocs_varray_t *ai); 61 extern void ocs_varray_lock(ocs_varray_t *ai); 62 extern void ocs_varray_unlock(ocs_varray_t *ai); 63 extern uint32_t ocs_varray_get_count(ocs_varray_t *ai); 64 65 66 /*************************************************************************** 67 * Circular buffer 68 * 69 */ 70 71 typedef struct ocs_cbuf_s ocs_cbuf_t; 72 73 extern ocs_cbuf_t *ocs_cbuf_alloc(ocs_os_handle_t os, uint32_t entry_count); 74 extern void ocs_cbuf_free(ocs_cbuf_t *cbuf); 75 extern void *ocs_cbuf_get(ocs_cbuf_t *cbuf, int32_t timeout_usec); 76 extern int32_t ocs_cbuf_put(ocs_cbuf_t *cbuf, void *elem); 77 extern int32_t ocs_cbuf_prime(ocs_cbuf_t *cbuf, ocs_array_t *array); 78 79 typedef struct { 80 void *vaddr; 81 uint32_t length; 82 } ocs_scsi_vaddr_len_t; 83 84 85 #define OCS_TEXTBUF_MAX_ALLOC_LEN (256*1024) 86 87 typedef struct { 88 ocs_list_link_t link; 89 uint8_t user_allocated:1; 90 uint8_t *buffer; 91 uint32_t buffer_length; 92 uint32_t buffer_written; 93 } ocs_textbuf_segment_t; 94 95 typedef struct { 96 ocs_t *ocs; 97 ocs_list_t segment_list; 98 uint8_t extendable:1; 99 uint32_t allocation_length; 100 uint32_t total_allocation_length; 101 uint32_t max_allocation_length; 102 } ocs_textbuf_t; 103 104 extern int32_t ocs_textbuf_alloc(ocs_t *ocs, ocs_textbuf_t *textbuf, uint32_t length); 105 extern uint32_t ocs_textbuf_initialized(ocs_textbuf_t *textbuf); 106 extern int32_t ocs_textbuf_init(ocs_t *ocs, ocs_textbuf_t *textbuf, void *buffer, uint32_t length); 107 extern void ocs_textbuf_free(ocs_t *ocs, ocs_textbuf_t *textbuf); 108 extern void ocs_textbuf_putc(ocs_textbuf_t *textbuf, uint8_t c); 109 extern void ocs_textbuf_puts(ocs_textbuf_t *textbuf, char *s); 110 __attribute__((format(printf,2,3))) 111 extern void ocs_textbuf_printf(ocs_textbuf_t *textbuf, const char *fmt, ...); 112 __attribute__((format(printf,2,0))) 113 extern void ocs_textbuf_vprintf(ocs_textbuf_t *textbuf, const char *fmt, va_list ap); 114 extern void ocs_textbuf_buffer(ocs_textbuf_t *textbuf, uint8_t *buffer, uint32_t buffer_length); 115 extern void ocs_textbuf_copy(ocs_textbuf_t *textbuf, uint8_t *buffer, uint32_t buffer_length); 116 extern int32_t ocs_textbuf_remaining(ocs_textbuf_t *textbuf); 117 extern void ocs_textbuf_reset(ocs_textbuf_t *textbuf); 118 extern uint8_t *ocs_textbuf_get_buffer(ocs_textbuf_t *textbuf); 119 extern int32_t ocs_textbuf_get_length(ocs_textbuf_t *textbuf); 120 extern int32_t ocs_textbuf_get_written(ocs_textbuf_t *textbuf); 121 extern uint8_t *ocs_textbuf_ext_get_buffer(ocs_textbuf_t *textbuf, uint32_t idx); 122 extern int32_t ocs_textbuf_ext_get_length(ocs_textbuf_t *textbuf, uint32_t idx); 123 extern int32_t ocs_textbuf_ext_get_written(ocs_textbuf_t *textbuf, uint32_t idx); 124 125 126 typedef struct ocs_pool_s ocs_pool_t; 127 128 extern ocs_pool_t *ocs_pool_alloc(ocs_os_handle_t os, uint32_t size, uint32_t count, uint32_t use_lock); 129 extern void ocs_pool_reset(ocs_pool_t *pool); 130 extern void ocs_pool_free(ocs_pool_t *pool); 131 extern void *ocs_pool_get(ocs_pool_t *pool); 132 extern void ocs_pool_put(ocs_pool_t *pool, void *item); 133 extern uint32_t ocs_pool_get_count(ocs_pool_t *pool); 134 extern void *ocs_pool_get_instance(ocs_pool_t *pool, uint32_t idx); 135 extern uint32_t ocs_pool_get_freelist_count(ocs_pool_t *pool); 136 137 138 /* Uncomment this line to enable logging extended queue history 139 */ 140 //#define OCS_DEBUG_QUEUE_HISTORY 141 142 143 /* Allocate maximum allowed (4M) */ 144 #if defined(OCS_DEBUG_QUEUE_HISTORY) 145 #define OCS_Q_HIST_SIZE (1000000UL) /* Size in words */ 146 #endif 147 148 #define OCS_LOG_ENABLE_SM_TRACE(ocs) (((ocs) != NULL) ? (((ocs)->logmask & (1U << 0)) != 0) : 0) 149 #define OCS_LOG_ENABLE_ELS_TRACE(ocs) (((ocs) != NULL) ? (((ocs)->logmask & (1U << 1)) != 0) : 0) 150 #define OCS_LOG_ENABLE_SCSI_TRACE(ocs) (((ocs) != NULL) ? (((ocs)->logmask & (1U << 2)) != 0) : 0) 151 #define OCS_LOG_ENABLE_SCSI_TGT_TRACE(ocs) (((ocs) != NULL) ? (((ocs)->logmask & (1U << 3)) != 0) : 0) 152 #define OCS_LOG_ENABLE_DOMAIN_SM_TRACE(ocs) (((ocs) != NULL) ? (((ocs)->logmask & (1U << 4)) != 0) : 0) 153 #define OCS_LOG_ENABLE_Q_FULL_BUSY_MSG(ocs) (((ocs) != NULL) ? (((ocs)->logmask & (1U << 5)) != 0) : 0) 154 #define OCS_LOG_ENABLE_IO_ERRORS(ocs) (((ocs) != NULL) ? (((ocs)->logmask & (1U << 6)) != 0) : 0) 155 156 157 extern void ocs_dump32(uint32_t, ocs_os_handle_t, const char *, void *, uint32_t); 158 extern void ocs_debug_enable(uint32_t mask); 159 extern void ocs_debug_disable(uint32_t mask); 160 extern int ocs_debug_is_enabled(uint32_t mask); 161 extern void ocs_debug_attach(void *); 162 extern void ocs_debug_detach(void *); 163 164 #if defined(OCS_DEBUG_QUEUE_HISTORY) 165 166 /** 167 * @brief Queue history footer 168 */ 169 typedef union ocs_q_hist_ftr_u { 170 uint32_t word; 171 struct { 172 #define Q_HIST_TYPE_LEN 3 173 #define Q_HIST_MASK_LEN 29 174 uint32_t mask:Q_HIST_MASK_LEN, 175 type:Q_HIST_TYPE_LEN; 176 } s; 177 } ocs_q_hist_ftr_t; 178 179 180 /** 181 * @brief WQE command mask lookup 182 */ 183 typedef struct ocs_q_hist_wqe_mask_s { 184 uint8_t command; 185 uint32_t mask; 186 } ocs_q_hist_wqe_mask_t; 187 188 /** 189 * @brief CQE mask lookup 190 */ 191 typedef struct ocs_q_hist_cqe_mask_s { 192 uint8_t ctype; 193 uint32_t :Q_HIST_MASK_LEN, 194 type:Q_HIST_TYPE_LEN; 195 uint32_t mask; 196 uint32_t mask_err; 197 } ocs_q_hist_cqe_mask_t; 198 199 /** 200 * @brief Queue history type 201 */ 202 typedef enum { 203 /* changes need to be made to ocs_queue_history_type_name() as well */ 204 OCS_Q_HIST_TYPE_WQE = 0, 205 OCS_Q_HIST_TYPE_CWQE, 206 OCS_Q_HIST_TYPE_CXABT, 207 OCS_Q_HIST_TYPE_MISC, 208 } ocs_q_hist_type_t; 209 210 static __inline const char * 211 ocs_queue_history_type_name(ocs_q_hist_type_t type) 212 { 213 switch (type) { 214 case OCS_Q_HIST_TYPE_WQE: return "wqe"; break; 215 case OCS_Q_HIST_TYPE_CWQE: return "wcqe"; break; 216 case OCS_Q_HIST_TYPE_CXABT: return "xacqe"; break; 217 case OCS_Q_HIST_TYPE_MISC: return "misc"; break; 218 default: return "unknown"; break; 219 } 220 } 221 222 typedef struct { 223 ocs_t *ocs; 224 uint32_t *q_hist; 225 uint32_t q_hist_index; 226 ocs_lock_t q_hist_lock; 227 } ocs_hw_q_hist_t; 228 229 extern void ocs_queue_history_cqe(ocs_hw_q_hist_t*, uint8_t, uint32_t *, uint8_t, uint32_t, uint32_t); 230 extern void ocs_queue_history_wq(ocs_hw_q_hist_t*, uint32_t *, uint32_t, uint32_t); 231 extern void ocs_queue_history_misc(ocs_hw_q_hist_t*, uint32_t *, uint32_t); 232 extern void ocs_queue_history_init(ocs_t *, ocs_hw_q_hist_t*); 233 extern void ocs_queue_history_free(ocs_hw_q_hist_t*); 234 extern uint32_t ocs_queue_history_prev_index(uint32_t); 235 extern uint8_t ocs_queue_history_q_info_enabled(void); 236 extern uint8_t ocs_queue_history_timestamp_enabled(void); 237 #else 238 #define ocs_queue_history_wq(...) 239 #define ocs_queue_history_cqe(...) 240 #define ocs_queue_history_misc(...) 241 #define ocs_queue_history_init(...) 242 #define ocs_queue_history_free(...) 243 #endif 244 245 #define OCS_DEBUG_ALWAYS (1U << 0) 246 #define OCS_DEBUG_ENABLE_MQ_DUMP (1U << 1) 247 #define OCS_DEBUG_ENABLE_CQ_DUMP (1U << 2) 248 #define OCS_DEBUG_ENABLE_WQ_DUMP (1U << 3) 249 #define OCS_DEBUG_ENABLE_EQ_DUMP (1U << 4) 250 #define OCS_DEBUG_ENABLE_SPARAM_DUMP (1U << 5) 251 252 extern void _ocs_assert(const char *cond, const char *filename, int linenum); 253 254 #define ocs_assert(cond, ...) \ 255 do { \ 256 if (!(cond)) { \ 257 _ocs_assert(#cond, __FILE__, __LINE__); \ 258 return __VA_ARGS__; \ 259 } \ 260 } while (0) 261 262 extern void ocs_dump_service_params(const char *label, void *sparms); 263 extern void ocs_display_sparams(const char *prelabel, const char *reqlabel, int dest, void *textbuf, void *sparams); 264 265 266 typedef struct { 267 uint16_t crc; 268 uint16_t app_tag; 269 uint32_t ref_tag; 270 } ocs_dif_t; 271 272 /* DIF guard calculations */ 273 extern uint16_t ocs_scsi_dif_calc_crc(const uint8_t *, uint32_t size, uint16_t crc); 274 extern uint16_t ocs_scsi_dif_calc_checksum(ocs_scsi_vaddr_len_t addrlen[], uint32_t addrlen_count); 275 276 /** 277 * @brief Power State change message types 278 * 279 */ 280 typedef enum { 281 OCS_PM_PREPARE = 1, 282 OCS_PM_SLEEP, 283 OCS_PM_HIBERNATE, 284 OCS_PM_RESUME, 285 } ocs_pm_msg_e; 286 287 /** 288 * @brief Power State values 289 * 290 */ 291 typedef enum { 292 OCS_PM_STATE_S0 = 0, 293 OCS_PM_STATE_S1, 294 OCS_PM_STATE_S2, 295 OCS_PM_STATE_S3, 296 OCS_PM_STATE_S4, 297 } ocs_pm_state_e; 298 299 typedef struct { 300 ocs_pm_state_e pm_state; /*<< Current PM state */ 301 } ocs_pm_context_t; 302 303 extern int32_t ocs_pm_request(ocs_t *ocs, ocs_pm_msg_e msg, int32_t (*callback)(ocs_t *ocs, int32_t status, void *arg), 304 void *arg); 305 extern ocs_pm_state_e ocs_pm_get_state(ocs_t *ocs); 306 extern const char *ocs_pm_get_state_string(ocs_t *ocs); 307 308 #define SPV_ROWLEN 256 309 #define SPV_DIM 3 310 311 312 /*! 313 * @defgroup spv Sparse Vector 314 */ 315 316 /** 317 * @brief Sparse vector structure. 318 */ 319 typedef struct sparse_vector_s { 320 ocs_os_handle_t os; 321 uint32_t max_idx; /**< maximum index value */ 322 void **array; /**< pointer to 3D array */ 323 } *sparse_vector_t; 324 325 extern void spv_del(sparse_vector_t spv); 326 extern sparse_vector_t spv_new(ocs_os_handle_t os); 327 extern void spv_set(sparse_vector_t sv, uint32_t idx, void *value); 328 extern void *spv_get(sparse_vector_t sv, uint32_t idx); 329 330 extern unsigned short t10crc16(const unsigned char *blk_adr, unsigned long blk_len, unsigned short crc); 331 332 typedef struct ocs_ramlog_s ocs_ramlog_t; 333 334 #define OCS_RAMLOG_DEFAULT_BUFFERS 5 335 336 extern ocs_ramlog_t *ocs_ramlog_init(ocs_t *ocs, uint32_t buffer_len, uint32_t buffer_count); 337 extern void ocs_ramlog_free(ocs_t *ocs, ocs_ramlog_t *ramlog); 338 extern void ocs_ramlog_clear(ocs_t *ocs, ocs_ramlog_t *ramlog, int clear_start_of_day, int clear_recent); 339 __attribute__((format(printf,2,3))) 340 extern int32_t ocs_ramlog_printf(void *os, const char *fmt, ...); 341 __attribute__((format(printf,2,0))) 342 extern int32_t ocs_ramlog_vprintf(ocs_ramlog_t *ramlog, const char *fmt, va_list ap); 343 extern int32_t ocs_ddump_ramlog(ocs_textbuf_t *textbuf, ocs_ramlog_t *ramlog); 344 345 #endif 346