1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* 27 * This header file contains definations for utility routines 28 * which can be used by all Solaris OFUV related kernel drivers 29 * and misc modules. The kernel modules using these APIs, should 30 * load sol_ofs using : 31 * ld -r -N misc/sol_ofs 32 * 33 * The APIs defined are : 34 * 1. User Objects 35 * 2. Linked Lists 36 * 3. Debug Routines 37 */ 38 #ifndef _SYS_IB_CLIENTS_OF_SOL_OFS_SOL_OFS_COMMON_H 39 #define _SYS_IB_CLIENTS_OF_SOL_OFS_SOL_OFS_COMMON_H 40 41 #ifdef __cplusplus 42 extern "C" { 43 #endif 44 45 #include <sys/types.h> 46 #include <sys/ksynch.h> 47 48 /* 49 * User Objects functions and structures. 50 */ 51 typedef enum { 52 /* User objects for sol_uverbs driver */ 53 SOL_UVERBS_UCTXT_UOBJ_TYPE = 0, 54 SOL_UVERBS_UPD_UOBJ_TYPE, 55 SOL_UVERBS_UAH_UOBJ_TYPE, 56 SOL_UVERBS_UMR_UOBJ_TYPE, 57 SOL_UVERBS_UCQ_UOBJ_TYPE, 58 SOL_UVERBS_USRQ_UOBJ_TYPE, 59 SOL_UVERBS_UQP_UOBJ_TYPE, 60 SOL_UVERBS_UFILE_UOBJ_TYPE, 61 62 /* User Objects for sol_ucma driver */ 63 SOL_UCMA_EVT_FILE_TYPE, 64 SOL_UCMA_CM_ID_TYPE, 65 SOL_UCMA_MCAST_TYPE 66 } sol_ofs_uobj_type_t; 67 68 typedef struct { 69 uint64_t uo_user_handle; 70 sol_ofs_uobj_type_t uo_type; 71 krwlock_t uo_lock; 72 uint32_t uo_id; 73 kmutex_t uo_reflock; 74 uint32_t uo_refcnt; 75 uint32_t uo_live; 76 size_t uo_uobj_sz; 77 } sol_ofs_uobj_t; 78 79 /* 80 * Objects are maintained in tables that allow an easy table ID to User Object 81 * mapping and can grow as resources are created. 82 */ 83 #define SOL_OFS_UO_BLKSZ 16 84 85 typedef struct { 86 int ofs_uo_blk_avail; 87 sol_ofs_uobj_t *ofs_uoblk_blks[SOL_OFS_UO_BLKSZ]; 88 } sol_ofs_uobj_blk_t; 89 90 typedef struct { 91 krwlock_t uobj_tbl_lock; 92 int uobj_tbl_used_blks; 93 uint_t uobj_tbl_num_blks; 94 size_t uobj_tbl_uo_sz; 95 int uobj_tbl_uo_cnt; 96 sol_ofs_uobj_blk_t **uobj_tbl_uo_root; 97 } sol_ofs_uobj_table_t; 98 99 /* User object table management routines */ 100 void sol_ofs_uobj_tbl_init(sol_ofs_uobj_table_t *, size_t); 101 void sol_ofs_uobj_tbl_fini(sol_ofs_uobj_table_t *); 102 103 void sol_ofs_uobj_init(sol_ofs_uobj_t *, uint64_t, sol_ofs_uobj_type_t); 104 void sol_ofs_uobj_ref(sol_ofs_uobj_t *); 105 void sol_ofs_uobj_deref(sol_ofs_uobj_t *, 106 void (*free_func)(sol_ofs_uobj_t *)); 107 void sol_ofs_uobj_put(sol_ofs_uobj_t *); 108 void sol_ofs_uobj_free(sol_ofs_uobj_t *uobj); 109 110 int sol_ofs_uobj_add(sol_ofs_uobj_table_t *, sol_ofs_uobj_t *); 111 sol_ofs_uobj_t *sol_ofs_uobj_remove(sol_ofs_uobj_table_t *, 112 sol_ofs_uobj_t *); 113 sol_ofs_uobj_t *sol_ofs_uobj_get_read(sol_ofs_uobj_table_t *, uint32_t); 114 sol_ofs_uobj_t *sol_ofs_uobj_get_write(sol_ofs_uobj_table_t *, uint32_t); 115 116 /* 117 * Generic linked list management functions 118 */ 119 typedef uchar_t bool; 120 #define FALSE 0 121 #define TRUE 1 122 #define INVALID_HANDLE 0xFFFFFFFF 123 #define MAX_HASH_SIZE 1024 124 125 /* 126 * Simple doubly linked list for opaque addresses. Protection must occur 127 * outside of the list. These behavior very much like the linux kernel 128 * lists, hence the familiar look of the API; but note there are 129 * some signficant differences, mainly the list header is not embedded 130 * in the element, so the container (typeof) constructs are not required. 131 */ 132 typedef struct llist_head { 133 struct llist_head *prv; 134 struct llist_head *nxt; 135 void *ptr; 136 } llist_head_t; 137 138 139 #define LLIST_HEAD_INIT(x) { &(x), &(x), NULL } 140 141 static inline void llist_head_init(llist_head_t *list, void *ptr) 142 { 143 list->prv = list->nxt = list; 144 list->ptr = ptr; 145 } 146 147 static inline void __llist_add(llist_head_t *new, llist_head_t *prv, 148 llist_head_t *nxt) 149 { 150 nxt->prv = new; 151 new->nxt = nxt; 152 new->prv = prv; 153 prv->nxt = new; 154 } 155 static inline void llist_add(llist_head_t *new, llist_head_t *head) 156 { 157 __llist_add(new, head, head->nxt); 158 } 159 160 static inline void llist_add_tail(llist_head_t *new, llist_head_t *head) 161 { 162 __llist_add(new, head->prv, head); 163 } 164 165 static inline void llist_del(llist_head_t *entry) 166 { 167 entry->nxt->prv = entry->prv; 168 entry->prv->nxt = entry->nxt; 169 } 170 171 static inline int llist_is_last(llist_head_t *list, llist_head_t *head) 172 { 173 return (list->nxt == head); 174 } 175 176 static inline int llist_empty(llist_head_t *head) 177 { 178 return (head->nxt == head); 179 } 180 181 #define list_for_each(_pos, _head) \ 182 for (_pos = (_head)->nxt; _pos != (_head); _pos = _pos->nxt) 183 #define list_for_each_safe(_pos, n, _head) \ 184 for (_pos = (_head)->nxt, n = _pos->nxt; _pos != (_head); \ 185 _pos = n, n = _pos->nxt) 186 187 /* 188 * Doubly linked per user context IB resource list definitions 189 * Protection must occur * outside of the list. 190 */ 191 typedef struct genlist_entry_s { 192 uintptr_t data; 193 void *data_context; 194 struct genlist_entry_s *next; 195 struct genlist_entry_s *prev; 196 } genlist_entry_t; 197 198 typedef struct genlist_s { 199 uint32_t count; 200 genlist_entry_t *head; 201 genlist_entry_t *tail; 202 } genlist_t; 203 204 205 genlist_entry_t *add_genlist(genlist_t *list, uintptr_t data, 206 void *data_context); 207 208 #define genlist_for_each(_pos, _head) \ 209 for (_pos = (_head)->head; _pos; _pos = _pos->next) 210 211 void delete_genlist(genlist_t *list, genlist_entry_t *entry); 212 213 genlist_entry_t *remove_genlist_head(genlist_t *list); 214 215 void insert_genlist_tail(genlist_t *list, genlist_entry_t *entry); 216 217 void flush_genlist(genlist_t *list); 218 219 bool genlist_empty(genlist_t *list); 220 221 static inline void init_genlist(genlist_t *list) 222 { 223 list->head = list->tail = NULL; 224 list->count = 0; 225 } 226 227 228 /* 229 * Debug printfs defines 230 */ 231 void sol_ofs_dprintf_l5(char *name, char *fmt, ...); 232 void sol_ofs_dprintf_l4(char *name, char *fmt, ...); 233 void sol_ofs_dprintf_l3(char *name, char *fmt, ...); 234 void sol_ofs_dprintf_l2(char *name, char *fmt, ...); 235 void sol_ofs_dprintf_l1(char *name, char *fmt, ...); 236 void sol_ofs_dprintf_l0(char *name, char *fmt, ...); 237 238 #define SOL_OFS_DPRINTF_L5 sol_ofs_dprintf_l5 239 #define SOL_OFS_DPRINTF_L4 sol_ofs_dprintf_l4 240 #define SOL_OFS_DPRINTF_L3 sol_ofs_dprintf_l3 241 #define SOL_OFS_DPRINTF_L2 sol_ofs_dprintf_l2 242 #define SOL_OFS_DPRINTF_L1 sol_ofs_dprintf_l1 243 #define SOL_OFS_DPRINTF_L0 sol_ofs_dprintf_l0 244 245 /* Misc */ 246 #define SOL_OFS_DRV_NAME_LEN 64 247 248 #ifdef __cplusplus 249 } 250 #endif 251 252 #endif /* _SYS_IB_CLIENTS_OF_SOL_OFS_SOL_OFS_COMMON_H */ 253