181 uint_t sleepflag, hermon_rsrc_t **hdl)
182 {
183 hermon_rsrc_pool_info_t *rsrc_pool;
184 hermon_rsrc_t *tmp_rsrc_hdl;
185 int flag, status = DDI_FAILURE;
186
187 ASSERT(state != NULL);
188 ASSERT(hdl != NULL);
189
190 rsrc_pool = &state->hs_rsrc_hdl[rsrc];
191 ASSERT(rsrc_pool != NULL);
192
193 /*
194 * Allocate space for the object used to track the resource handle
195 */
196 flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
197 tmp_rsrc_hdl = kmem_cache_alloc(state->hs_rsrc_cache, flag);
198 if (tmp_rsrc_hdl == NULL) {
199 return (DDI_FAILURE);
200 }
201 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tmp_rsrc_hdl))
202
203 /*
204 * Set rsrc_hdl type. This is later used by the hermon_rsrc_free call
205 * to know what type of resource is being freed.
206 */
207 tmp_rsrc_hdl->rsrc_type = rsrc;
208
209 /*
210 * Depending on resource type, call the appropriate alloc routine
211 */
212 switch (rsrc) {
213 case HERMON_IN_MBOX:
214 case HERMON_OUT_MBOX:
215 case HERMON_INTR_IN_MBOX:
216 case HERMON_INTR_OUT_MBOX:
217 status = hermon_rsrc_mbox_alloc(rsrc_pool, num, tmp_rsrc_hdl);
218 break;
219
220 case HERMON_DMPT:
221 /* Allocate "num" (contiguous/aligned for FEXCH) DMPTs */
306 uint_t sleepflag, hermon_rsrc_t **hdl)
307 {
308 hermon_rsrc_pool_info_t *rsrc_pool;
309 hermon_rsrc_t *tmp_rsrc_hdl;
310 int flag, status = DDI_FAILURE;
311
312 ASSERT(state != NULL);
313 ASSERT(hdl != NULL);
314
315 rsrc_pool = &state->hs_rsrc_hdl[rsrc];
316 ASSERT(rsrc_pool != NULL);
317
318 /*
319 * Allocate space for the object used to track the resource handle
320 */
321 flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
322 tmp_rsrc_hdl = kmem_cache_alloc(state->hs_rsrc_cache, flag);
323 if (tmp_rsrc_hdl == NULL) {
324 return (DDI_FAILURE);
325 }
326 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*tmp_rsrc_hdl))
327
328 /*
329 * Set rsrc_hdl type. This is later used by the hermon_rsrc_free call
330 * to know what type of resource is being freed.
331 */
332 tmp_rsrc_hdl->rsrc_type = rsrc;
333
334 switch (rsrc) {
335 case HERMON_QPC:
336 case HERMON_DMPT:
337 case HERMON_MTT:
338 /*
339 * Reserve num resources, naturally aligned (N * num).
340 */
341 status = hermon_rsrc_hw_entry_reserve(rsrc_pool, num, num,
342 sleepflag, tmp_rsrc_hdl);
343 break;
344
345 default:
346 HERMON_WARNING(state, "unexpected resource type in reserve ");
2066 * the offset indicated by hdl->ar_indx) in the span in question.
2067 * In either of these cases, we'll be breaking up our allocation
2068 * into multiple spans.
2069 */
2070 state = pool_info->rsrc_state;
2071 type = pool_info->rsrc_type;
2072 icm_table = &state->hs_icm[type];
2073
2074 rindx = hdl->hr_indx;
2075 hermon_index(index1, index2, rindx, icm_table, span_offset);
2076
2077 if (hermon_rsrc_verbose) {
2078 IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry_icm_confirm: "
2079 "type (0x%x) num (0x%x) length (0x%x) index (0x%x, 0x%x): ",
2080 type, num, hdl->hr_len, index1, index2);
2081 }
2082
2083 mutex_enter(&icm_table->icm_table_lock);
2084 hermon_bitmap(bitmap, dma_info, icm_table, index1, num_to_hdl);
2085 while (num) {
2086 #ifndef __lock_lint
2087 while (icm_table->icm_busy) {
2088 cv_wait(&icm_table->icm_table_cv,
2089 &icm_table->icm_table_lock);
2090 }
2091 #endif
2092 if (!HERMON_BMAP_BIT_ISSET(bitmap, index2)) {
2093 /* Allocate ICM for this span */
2094 icm_table->icm_busy = 1;
2095 mutex_exit(&icm_table->icm_table_lock);
2096 status = hermon_icm_alloc(state, type, index1, index2);
2097 mutex_enter(&icm_table->icm_table_lock);
2098 icm_table->icm_busy = 0;
2099 cv_broadcast(&icm_table->icm_table_cv);
2100 if (status != DDI_SUCCESS) {
2101 goto fail_alloc;
2102 }
2103 if (hermon_rsrc_verbose) {
2104 IBTF_DPRINTF_L2("hermon", "hermon_rsrc_"
2105 "hw_entry_icm_confirm: ALLOCATED ICM: "
2106 "type (0x%x) index (0x%x, 0x%x)",
2107 type, index1, index2);
2108 }
2109 }
2110
2111 /*
2342 * hermon_rsrc_pdhdl_alloc()
2343 * Context: Can be called from interrupt or base context.
2344 */
2345 static int
2346 hermon_rsrc_pdhdl_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t sleepflag,
2347 hermon_rsrc_t *hdl)
2348 {
2349 hermon_pdhdl_t addr;
2350 void *tmpaddr;
2351 int flag, status;
2352
2353 ASSERT(pool_info != NULL);
2354 ASSERT(hdl != NULL);
2355
2356 /* Allocate the software handle */
2357 status = hermon_rsrc_swhdl_alloc(pool_info, sleepflag, hdl);
2358 if (status != DDI_SUCCESS) {
2359 return (DDI_FAILURE);
2360 }
2361 addr = (hermon_pdhdl_t)hdl->hr_addr;
2362 _NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(*addr))
2363
2364 /* Allocate a PD number for the handle */
2365 flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
2366 tmpaddr = vmem_alloc(pool_info->rsrc_vmp, 1, flag);
2367 if (tmpaddr == NULL) {
2368 /* No more PD number entries available */
2369 hermon_rsrc_swhdl_free(pool_info, hdl);
2370 return (DDI_FAILURE);
2371 }
2372 addr->pd_pdnum = (uint32_t)(uintptr_t)tmpaddr;
2373 addr->pd_rsrcp = hdl;
2374 hdl->hr_indx = addr->pd_pdnum;
2375
2376 return (DDI_SUCCESS);
2377 }
2378
2379
2380 /*
2381 * hermon_rsrc_pdhdl_free()
2382 * Context: Can be called from interrupt or base context.
|
181 uint_t sleepflag, hermon_rsrc_t **hdl)
182 {
183 hermon_rsrc_pool_info_t *rsrc_pool;
184 hermon_rsrc_t *tmp_rsrc_hdl;
185 int flag, status = DDI_FAILURE;
186
187 ASSERT(state != NULL);
188 ASSERT(hdl != NULL);
189
190 rsrc_pool = &state->hs_rsrc_hdl[rsrc];
191 ASSERT(rsrc_pool != NULL);
192
193 /*
194 * Allocate space for the object used to track the resource handle
195 */
196 flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
197 tmp_rsrc_hdl = kmem_cache_alloc(state->hs_rsrc_cache, flag);
198 if (tmp_rsrc_hdl == NULL) {
199 return (DDI_FAILURE);
200 }
201
202 /*
203 * Set rsrc_hdl type. This is later used by the hermon_rsrc_free call
204 * to know what type of resource is being freed.
205 */
206 tmp_rsrc_hdl->rsrc_type = rsrc;
207
208 /*
209 * Depending on resource type, call the appropriate alloc routine
210 */
211 switch (rsrc) {
212 case HERMON_IN_MBOX:
213 case HERMON_OUT_MBOX:
214 case HERMON_INTR_IN_MBOX:
215 case HERMON_INTR_OUT_MBOX:
216 status = hermon_rsrc_mbox_alloc(rsrc_pool, num, tmp_rsrc_hdl);
217 break;
218
219 case HERMON_DMPT:
220 /* Allocate "num" (contiguous/aligned for FEXCH) DMPTs */
305 uint_t sleepflag, hermon_rsrc_t **hdl)
306 {
307 hermon_rsrc_pool_info_t *rsrc_pool;
308 hermon_rsrc_t *tmp_rsrc_hdl;
309 int flag, status = DDI_FAILURE;
310
311 ASSERT(state != NULL);
312 ASSERT(hdl != NULL);
313
314 rsrc_pool = &state->hs_rsrc_hdl[rsrc];
315 ASSERT(rsrc_pool != NULL);
316
317 /*
318 * Allocate space for the object used to track the resource handle
319 */
320 flag = (sleepflag == HERMON_SLEEP) ? KM_SLEEP : KM_NOSLEEP;
321 tmp_rsrc_hdl = kmem_cache_alloc(state->hs_rsrc_cache, flag);
322 if (tmp_rsrc_hdl == NULL) {
323 return (DDI_FAILURE);
324 }
325
326 /*
327 * Set rsrc_hdl type. This is later used by the hermon_rsrc_free call
328 * to know what type of resource is being freed.
329 */
330 tmp_rsrc_hdl->rsrc_type = rsrc;
331
332 switch (rsrc) {
333 case HERMON_QPC:
334 case HERMON_DMPT:
335 case HERMON_MTT:
336 /*
337 * Reserve num resources, naturally aligned (N * num).
338 */
339 status = hermon_rsrc_hw_entry_reserve(rsrc_pool, num, num,
340 sleepflag, tmp_rsrc_hdl);
341 break;
342
343 default:
344 HERMON_WARNING(state, "unexpected resource type in reserve ");
2064 * the offset indicated by hdl->ar_indx) in the span in question.
2065 * In either of these cases, we'll be breaking up our allocation
2066 * into multiple spans.
2067 */
2068 state = pool_info->rsrc_state;
2069 type = pool_info->rsrc_type;
2070 icm_table = &state->hs_icm[type];
2071
2072 rindx = hdl->hr_indx;
2073 hermon_index(index1, index2, rindx, icm_table, span_offset);
2074
2075 if (hermon_rsrc_verbose) {
2076 IBTF_DPRINTF_L2("hermon", "hermon_rsrc_hw_entry_icm_confirm: "
2077 "type (0x%x) num (0x%x) length (0x%x) index (0x%x, 0x%x): ",
2078 type, num, hdl->hr_len, index1, index2);
2079 }
2080
2081 mutex_enter(&icm_table->icm_table_lock);
2082 hermon_bitmap(bitmap, dma_info, icm_table, index1, num_to_hdl);
2083 while (num) {
2084 while (icm_table->icm_busy) {
2085 cv_wait(&icm_table->icm_table_cv,
2086 &icm_table->icm_table_lock);
2087 }
2088 if (!HERMON_BMAP_BIT_ISSET(bitmap, index2)) {
2089 /* Allocate ICM for this span */
2090 icm_table->icm_busy = 1;
2091 mutex_exit(&icm_table->icm_table_lock);
2092 status = hermon_icm_alloc(state, type, index1, index2);
2093 mutex_enter(&icm_table->icm_table_lock);
2094 icm_table->icm_busy = 0;
2095 cv_broadcast(&icm_table->icm_table_cv);
2096 if (status != DDI_SUCCESS) {
2097 goto fail_alloc;
2098 }
2099 if (hermon_rsrc_verbose) {
2100 IBTF_DPRINTF_L2("hermon", "hermon_rsrc_"
2101 "hw_entry_icm_confirm: ALLOCATED ICM: "
2102 "type (0x%x) index (0x%x, 0x%x)",
2103 type, index1, index2);
2104 }
2105 }
2106
2107 /*
2338 * hermon_rsrc_pdhdl_alloc()
2339 * Context: Can be called from interrupt or base context.
2340 */
2341 static int
2342 hermon_rsrc_pdhdl_alloc(hermon_rsrc_pool_info_t *pool_info, uint_t sleepflag,
2343 hermon_rsrc_t *hdl)
2344 {
2345 hermon_pdhdl_t addr;
2346 void *tmpaddr;
2347 int flag, status;
2348
2349 ASSERT(pool_info != NULL);
2350 ASSERT(hdl != NULL);
2351
2352 /* Allocate the software handle */
2353 status = hermon_rsrc_swhdl_alloc(pool_info, sleepflag, hdl);
2354 if (status != DDI_SUCCESS) {
2355 return (DDI_FAILURE);
2356 }
2357 addr = (hermon_pdhdl_t)hdl->hr_addr;
2358
2359 /* Allocate a PD number for the handle */
2360 flag = (sleepflag == HERMON_SLEEP) ? VM_SLEEP : VM_NOSLEEP;
2361 tmpaddr = vmem_alloc(pool_info->rsrc_vmp, 1, flag);
2362 if (tmpaddr == NULL) {
2363 /* No more PD number entries available */
2364 hermon_rsrc_swhdl_free(pool_info, hdl);
2365 return (DDI_FAILURE);
2366 }
2367 addr->pd_pdnum = (uint32_t)(uintptr_t)tmpaddr;
2368 addr->pd_rsrcp = hdl;
2369 hdl->hr_indx = addr->pd_pdnum;
2370
2371 return (DDI_SUCCESS);
2372 }
2373
2374
2375 /*
2376 * hermon_rsrc_pdhdl_free()
2377 * Context: Can be called from interrupt or base context.
|