72 kmutex_t ibtl_clnt_list_mutex;
73
74 /* Lock for the race between the client and CM to free QPs. */
75 kmutex_t ibtl_free_qp_mutex;
76
77 /* Lock for the race between the client closing the HCA and QPN being freed. */
78 kcondvar_t ibtl_close_hca_cv;
79
80 /* Global List of HCA Devices, and associated mutex. */
81 struct ibtl_hca_devinfo_s *ibtl_hca_list = NULL;
82
83 /* Well-known async handlers and associated client private. */
84 ibt_async_handler_t ibtl_cm_async_handler;
85 ibt_async_handler_t ibtl_dm_async_handler;
86 ibt_async_handler_t ibtl_ibma_async_handler;
87 void *ibtl_cm_clnt_private;
88 void *ibtl_dm_clnt_private;
89 void *ibtl_ibma_clnt_private;
90
91 extern int ib_hw_status;
92 _NOTE(SCHEME_PROTECTS_DATA("Scheme protects data", ib_hw_status))
93
94 /*
95 * Misc Module Declarations.
96 */
97 extern struct mod_ops mod_miscops;
98 static struct modlmisc modlmisc = {
99 &mod_miscops, /* Type of module - misc. */
100 "IB Transport Layer" /* Name of the Module. */
101 };
102
103 static struct modlinkage modlinkage = {
104 MODREV_1, (void *)&modlmisc, NULL
105 };
106
107 static void ibtl_kstat_init(ibtl_hca_devinfo_t *);
108 static void ibtl_kstat_fini(ibtl_hca_devinfo_t *);
109 static void ibtl_kstat_stats_create(ibtl_hca_devinfo_t *, uint_t);
110 static void ibtl_kstat_pkeys_create(ibtl_hca_devinfo_t *, uint_t);
111
112 extern kmutex_t ibtl_part_attr_mutex;
289 "DM is already attached.");
290 mutex_exit(&ibtl_clnt_list_mutex);
291 return (IBT_INVALID_PARAM);
292 }
293 ibtl_dm_async_handler = mod_infop->mi_async_handler;
294 ibtl_dm_clnt_private = clnt_private;
295 } else if (mod_infop->mi_clnt_class == IBT_IBMA) {
296 if (ibtl_ibma_async_handler != NULL) {
297 IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
298 "IBMF is already attached.");
299 mutex_exit(&ibtl_clnt_list_mutex);
300 return (IBT_INVALID_PARAM);
301 }
302 ibtl_ibma_async_handler = mod_infop->mi_async_handler;
303 ibtl_ibma_clnt_private = clnt_private;
304 }
305
306 /* Allocate the memory for per-client-device info structure */
307 clntp = kmem_zalloc(sizeof (ibtl_clnt_t), KM_SLEEP);
308
309 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(clntp->clnt_modinfop,
310 clntp->clnt_dip, clntp->clnt_name, clntp->clnt_async_cnt,
311 clntp->clnt_private))
312 /* Update the Client info structure */
313 clntp->clnt_modinfop = mod_infop; /* IBT Client's Mod Info */
314 clntp->clnt_private = clnt_private; /* IBT Client's private */
315 clntp->clnt_dip = arg; /* IBT Client's dip */
316 clntp->clnt_async_cnt = 0;
317 /* using a count of 7 below guarantees it is NULL terminated */
318 (void) strncpy(clntp->clnt_name, mod_infop->mi_clnt_name, 7);
319 _NOTE(NOW_VISIBLE_TO_OTHER_THREADS(clntp->clnt_modinfop,
320 clntp->clnt_dip, clntp->clnt_name, clntp->clnt_async_cnt,
321 clntp->clnt_private))
322
323 /*
324 * Update Client Device Instance List.
325 */
326 clntp->clnt_list_link = ibtl_clnt_list;
327 ibtl_clnt_list = clntp;
328 mutex_exit(&ibtl_clnt_list_mutex);
329
330 /*
331 * The ibt_hdl_p is a opaque handle which is the address of
332 * ibt_clnt_t structure passed back to the clients.
333 * The client will pass on this handle in its future calls to IBTF.
334 */
335 *ibt_hdl_p = clntp;
336
337 return (IBT_SUCCESS);
338 }
339
340
341 /*
1140
1141 for (i = 0; i < nports; i++, pks++) {
1142 pks->pks_hca_devp = hca_devp;
1143 pks->pks_port_num = i + 1;
1144 ibtl_kstat_stats_create(hca_devp, i + 1);
1145 ibtl_kstat_pkeys_create(hca_devp, i + 1);
1146 }
1147 }
1148
1149 /*
1150 * Delete kstats on all ports of the HCA.
1151 */
1152 static void
1153 ibtl_kstat_fini(ibtl_hca_devinfo_t *hca_devp)
1154 {
1155 ibtl_hca_port_kstat_t *pks;
1156 int i;
1157
1158 IBTF_DPRINTF_L3(ibtf, "ibtl_kstat_fini(hca_devp = 0x%p)", hca_devp);
1159
1160 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*hca_devp))
1161
1162 pks = hca_devp->hd_hca_port_ks_info;
1163 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*pks))
1164
1165 if (pks == NULL)
1166 return;
1167
1168 for (i = 0; i < hca_devp->hd_hca_attr->hca_nports; i++, pks++) {
1169 if (pks->pks_stats_ksp)
1170 kstat_delete(pks->pks_stats_ksp);
1171
1172 if (pks->pks_pkeys_ksp) {
1173 ASSERT(!MUTEX_HELD(&ibtl_clnt_list_mutex));
1174 kstat_delete(pks->pks_pkeys_ksp);
1175 }
1176 }
1177
1178 kmem_free(hca_devp->hd_hca_port_ks_info,
1179 hca_devp->hd_hca_port_ks_info_len);
1180 }
1181
1182 /*
1183 * Update "stats" kstat.
1256 kstat_install(ksp);
1257 }
1258
1259 /*
1260 * Update "pkeys" kstat.
1261 *
1262 * Called by kstat framework. Since ks_lock was set to ibtl_clnt_list_mutex
1263 * at the time of the kstat creation, kstat framework will hold this lock
1264 * while calling this function.
1265 */
1266 static int
1267 ibtl_kstat_pkeys_update(kstat_t *ksp, int rw)
1268 {
1269 ibtl_hca_port_kstat_t *pks;
1270 ibtl_hca_devinfo_t *hca_devp;
1271 ibt_hca_portinfo_t *p;
1272
1273 IBTF_DPRINTF_L4(ibtf, "ibtl_kstat_pkeys_update(ksp = 0x%p, rw = %d)",
1274 ksp, rw);
1275
1276 #ifndef __lock_lint
1277 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1278 #endif
1279
1280 if (rw == KSTAT_WRITE)
1281 return (EACCES);
1282
1283 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*ksp))
1284
1285 pks = ksp->ks_private;
1286 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*pks))
1287
1288 hca_devp = pks->pks_hca_devp;
1289 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*hca_devp))
1290
1291 /*
1292 * Point kstat data to the pkey table in the portinfo cache.
1293 */
1294
1295 p = hca_devp->hd_portinfop + pks->pks_port_num - 1;
1296
1297 ksp->ks_data = p->p_pkey_tbl;
1298 ksp->ks_ndata = p->p_pkey_tbl_sz;
1299 ksp->ks_data_size = p->p_pkey_tbl_sz * sizeof (ib_pkey_t);
1300
1301 return (0);
1302 }
1303
1304 /*
1305 * Create "pkeys" kstat for the specified HCA port in the form:
1306 * <hca_driver_name><instance_number>/port<port_num>/pkeys
1307 *
1308 * Currently kstat framework allows only some fixed data types as named
1309 * data components under a named kstat. Due to this limitation it is not
|
72 kmutex_t ibtl_clnt_list_mutex;
73
74 /* Lock for the race between the client and CM to free QPs. */
75 kmutex_t ibtl_free_qp_mutex;
76
77 /* Lock for the race between the client closing the HCA and QPN being freed. */
78 kcondvar_t ibtl_close_hca_cv;
79
80 /* Global List of HCA Devices, and associated mutex. */
81 struct ibtl_hca_devinfo_s *ibtl_hca_list = NULL;
82
83 /* Well-known async handlers and associated client private. */
84 ibt_async_handler_t ibtl_cm_async_handler;
85 ibt_async_handler_t ibtl_dm_async_handler;
86 ibt_async_handler_t ibtl_ibma_async_handler;
87 void *ibtl_cm_clnt_private;
88 void *ibtl_dm_clnt_private;
89 void *ibtl_ibma_clnt_private;
90
91 extern int ib_hw_status;
92
93 /*
94 * Misc Module Declarations.
95 */
96 extern struct mod_ops mod_miscops;
97 static struct modlmisc modlmisc = {
98 &mod_miscops, /* Type of module - misc. */
99 "IB Transport Layer" /* Name of the Module. */
100 };
101
102 static struct modlinkage modlinkage = {
103 MODREV_1, (void *)&modlmisc, NULL
104 };
105
106 static void ibtl_kstat_init(ibtl_hca_devinfo_t *);
107 static void ibtl_kstat_fini(ibtl_hca_devinfo_t *);
108 static void ibtl_kstat_stats_create(ibtl_hca_devinfo_t *, uint_t);
109 static void ibtl_kstat_pkeys_create(ibtl_hca_devinfo_t *, uint_t);
110
111 extern kmutex_t ibtl_part_attr_mutex;
288 "DM is already attached.");
289 mutex_exit(&ibtl_clnt_list_mutex);
290 return (IBT_INVALID_PARAM);
291 }
292 ibtl_dm_async_handler = mod_infop->mi_async_handler;
293 ibtl_dm_clnt_private = clnt_private;
294 } else if (mod_infop->mi_clnt_class == IBT_IBMA) {
295 if (ibtl_ibma_async_handler != NULL) {
296 IBTF_DPRINTF_L1(ibtf, "ibt_attach: "
297 "IBMF is already attached.");
298 mutex_exit(&ibtl_clnt_list_mutex);
299 return (IBT_INVALID_PARAM);
300 }
301 ibtl_ibma_async_handler = mod_infop->mi_async_handler;
302 ibtl_ibma_clnt_private = clnt_private;
303 }
304
305 /* Allocate the memory for per-client-device info structure */
306 clntp = kmem_zalloc(sizeof (ibtl_clnt_t), KM_SLEEP);
307
308 /* Update the Client info structure */
309 clntp->clnt_modinfop = mod_infop; /* IBT Client's Mod Info */
310 clntp->clnt_private = clnt_private; /* IBT Client's private */
311 clntp->clnt_dip = arg; /* IBT Client's dip */
312 clntp->clnt_async_cnt = 0;
313 /* using a count of 7 below guarantees it is NULL terminated */
314 (void) strncpy(clntp->clnt_name, mod_infop->mi_clnt_name, 7);
315
316 /*
317 * Update Client Device Instance List.
318 */
319 clntp->clnt_list_link = ibtl_clnt_list;
320 ibtl_clnt_list = clntp;
321 mutex_exit(&ibtl_clnt_list_mutex);
322
323 /*
324 * The ibt_hdl_p is a opaque handle which is the address of
325 * ibt_clnt_t structure passed back to the clients.
326 * The client will pass on this handle in its future calls to IBTF.
327 */
328 *ibt_hdl_p = clntp;
329
330 return (IBT_SUCCESS);
331 }
332
333
334 /*
1133
1134 for (i = 0; i < nports; i++, pks++) {
1135 pks->pks_hca_devp = hca_devp;
1136 pks->pks_port_num = i + 1;
1137 ibtl_kstat_stats_create(hca_devp, i + 1);
1138 ibtl_kstat_pkeys_create(hca_devp, i + 1);
1139 }
1140 }
1141
1142 /*
1143 * Delete kstats on all ports of the HCA.
1144 */
1145 static void
1146 ibtl_kstat_fini(ibtl_hca_devinfo_t *hca_devp)
1147 {
1148 ibtl_hca_port_kstat_t *pks;
1149 int i;
1150
1151 IBTF_DPRINTF_L3(ibtf, "ibtl_kstat_fini(hca_devp = 0x%p)", hca_devp);
1152
1153 pks = hca_devp->hd_hca_port_ks_info;
1154
1155 if (pks == NULL)
1156 return;
1157
1158 for (i = 0; i < hca_devp->hd_hca_attr->hca_nports; i++, pks++) {
1159 if (pks->pks_stats_ksp)
1160 kstat_delete(pks->pks_stats_ksp);
1161
1162 if (pks->pks_pkeys_ksp) {
1163 ASSERT(!MUTEX_HELD(&ibtl_clnt_list_mutex));
1164 kstat_delete(pks->pks_pkeys_ksp);
1165 }
1166 }
1167
1168 kmem_free(hca_devp->hd_hca_port_ks_info,
1169 hca_devp->hd_hca_port_ks_info_len);
1170 }
1171
1172 /*
1173 * Update "stats" kstat.
1246 kstat_install(ksp);
1247 }
1248
1249 /*
1250 * Update "pkeys" kstat.
1251 *
1252 * Called by kstat framework. Since ks_lock was set to ibtl_clnt_list_mutex
1253 * at the time of the kstat creation, kstat framework will hold this lock
1254 * while calling this function.
1255 */
1256 static int
1257 ibtl_kstat_pkeys_update(kstat_t *ksp, int rw)
1258 {
1259 ibtl_hca_port_kstat_t *pks;
1260 ibtl_hca_devinfo_t *hca_devp;
1261 ibt_hca_portinfo_t *p;
1262
1263 IBTF_DPRINTF_L4(ibtf, "ibtl_kstat_pkeys_update(ksp = 0x%p, rw = %d)",
1264 ksp, rw);
1265
1266 ASSERT(MUTEX_HELD(&ibtl_clnt_list_mutex));
1267
1268 if (rw == KSTAT_WRITE)
1269 return (EACCES);
1270
1271 pks = ksp->ks_private;
1272 hca_devp = pks->pks_hca_devp;
1273
1274 /*
1275 * Point kstat data to the pkey table in the portinfo cache.
1276 */
1277
1278 p = hca_devp->hd_portinfop + pks->pks_port_num - 1;
1279
1280 ksp->ks_data = p->p_pkey_tbl;
1281 ksp->ks_ndata = p->p_pkey_tbl_sz;
1282 ksp->ks_data_size = p->p_pkey_tbl_sz * sizeof (ib_pkey_t);
1283
1284 return (0);
1285 }
1286
1287 /*
1288 * Create "pkeys" kstat for the specified HCA port in the form:
1289 * <hca_driver_name><instance_number>/port<port_num>/pkeys
1290 *
1291 * Currently kstat framework allows only some fixed data types as named
1292 * data components under a named kstat. Due to this limitation it is not
|