1219820Sjeff/* 2219820Sjeff * Copyright (c) 2004-2006 Voltaire, Inc. All rights reserved. 3219820Sjeff * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4219820Sjeff * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5219820Sjeff * 6219820Sjeff * This software is available to you under a choice of one of two 7219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 8219820Sjeff * General Public License (GPL) Version 2, available from the file 9219820Sjeff * COPYING in the main directory of this source tree, or the 10219820Sjeff * OpenIB.org BSD license below: 11219820Sjeff * 12219820Sjeff * Redistribution and use in source and binary forms, with or 13219820Sjeff * without modification, are permitted provided that the following 14219820Sjeff * conditions are met: 15219820Sjeff * 16219820Sjeff * - Redistributions of source code must retain the above 17219820Sjeff * copyright notice, this list of conditions and the following 18219820Sjeff * disclaimer. 19219820Sjeff * 20219820Sjeff * - Redistributions in binary form must reproduce the above 21219820Sjeff * copyright notice, this list of conditions and the following 22219820Sjeff * disclaimer in the documentation and/or other materials 23219820Sjeff * provided with the distribution. 24219820Sjeff * 25219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32219820Sjeff * SOFTWARE. 33219820Sjeff * 34219820Sjeff */ 35219820Sjeff 36219820Sjeff#if HAVE_CONFIG_H 37219820Sjeff# include <config.h> 38219820Sjeff#endif /* HAVE_CONFIG_H */ 39219820Sjeff 40219820Sjeff#include <math.h> 41219820Sjeff#include <stdlib.h> 42219820Sjeff#include <opensm/osm_helper.h> 43219820Sjeff#include <opensm/osm_log.h> 44219820Sjeff#include <vendor/osm_vendor.h> 45219820Sjeff#include <vendor/osm_vendor_api.h> 46219820Sjeff#include <opensm/osm_mad_pool.h> 47219820Sjeff 48219820Sjeff#if defined(OSM_VENDOR_INTF_MTL) | defined(OSM_VENDOR_INTF_TS) 49219820Sjeff 50219820Sjeff#include <vendor/osm_vendor_mtl_transaction_mgr.h> 51219820Sjeff#ifdef OSM_VENDOR_INTF_MTL 52219820Sjeff#include <vendor/osm_mtl_bind.h> 53219820Sjeff#endif 54219820Sjeff 55219820Sjeff/* this is the callback function of the timer */ 56219820Sjeffvoid __osm_transaction_mgr_callback(IN void *context) 57219820Sjeff{ 58219820Sjeff osm_transaction_mgr_t *trans_mgr_p; 59219820Sjeff osm_vendor_t *p_vend = (osm_vendor_t *) context; 60219820Sjeff cl_list_item_t *p_list_item; 61219820Sjeff cl_list_item_t *p_list_next_item; 62219820Sjeff osm_madw_req_t *osm_madw_req_p; 63219820Sjeff uint64_t current_time; /* [usec] */ 64219820Sjeff uint32_t new_timeout; /* [msec] */ 65219820Sjeff cl_status_t cl_status; 66219820Sjeff ib_mad_t *p_mad; 67219820Sjeff#ifdef OSM_VENDOR_INTF_MTL 68219820Sjeff osm_mtl_bind_info_t *p_bind; 69219820Sjeff#else 70219820Sjeff osm_ts_bind_info_t *p_bind; 71219820Sjeff#endif 72219820Sjeff cl_list_t tmp_madw_p_list; /* this list will include all the madw_p that should be removed. */ 73219820Sjeff cl_list_t retry_madw_p_list; /* this list will include all the madw_p that were retried and need to be removed. */ 74219820Sjeff osm_madw_t *madw_p; 75219820Sjeff 76219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 77219820Sjeff 78219820Sjeff trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr; 79219820Sjeff 80219820Sjeff /* initialize the tmp_madw_p_list */ 81219820Sjeff cl_list_construct(&tmp_madw_p_list); 82219820Sjeff cl_status = cl_list_init(&tmp_madw_p_list, 50); 83219820Sjeff if (cl_status != CL_SUCCESS) { 84219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 85219820Sjeff "__osm_transaction_mgr_callback : ERROR 1000: " 86219820Sjeff "Failed to create tmp_madw_p_list\n"); 87219820Sjeff } 88219820Sjeff 89219820Sjeff cl_list_construct(&retry_madw_p_list); 90219820Sjeff cl_status = cl_list_init(&retry_madw_p_list, 50); 91219820Sjeff if (cl_status != CL_SUCCESS) { 92219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 93219820Sjeff "__osm_transaction_mgr_callback : ERROR 1000: " 94219820Sjeff "Failed to create retry_madw_p_list\n"); 95219820Sjeff } 96219820Sjeff 97219820Sjeff current_time = cl_get_time_stamp(); 98219820Sjeff cl_spinlock_acquire(&(trans_mgr_p->transaction_mgr_lock)); 99219820Sjeff p_list_item = cl_qlist_head(trans_mgr_p->madw_reqs_list_p); 100219820Sjeff if (p_list_item == cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) { 101219820Sjeff /* the list is empty - nothing to do */ 102219820Sjeff cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock); 103219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 104219820Sjeff "__osm_transaction_mgr_callback : Nothing to do\n"); 105219820Sjeff goto Exit; 106219820Sjeff } 107219820Sjeff 108219820Sjeff /* non empty list: */ 109219820Sjeff 110219820Sjeff /* get the osm_madw_req_p */ 111219820Sjeff osm_madw_req_p = PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item); 112219820Sjeff 113219820Sjeff while (osm_madw_req_p->waking_time <= current_time) { 114219820Sjeff /* this object was supposed to have gotten a response */ 115219820Sjeff /* we need to decide if we need to retry or done with it. */ 116219820Sjeff if (osm_madw_req_p->retry_cnt > 0) { 117219820Sjeff /* add to the list of the retrys : */ 118219820Sjeff cl_list_insert_tail(&retry_madw_p_list, osm_madw_req_p); 119219820Sjeff 120219820Sjeff /* update wakeup time and retry count */ 121219820Sjeff osm_madw_req_p->waking_time = 122219820Sjeff p_vend->timeout * 1000 + cl_get_time_stamp(); 123219820Sjeff osm_madw_req_p->retry_cnt--; 124219820Sjeff 125219820Sjeff /* make sure we will get some timer call if not earlier */ 126219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 127219820Sjeff "__osm_transaction_mgr_callback : Timer restart:%u\n", 128219820Sjeff p_vend->timeout); 129219820Sjeff 130219820Sjeff cl_status = 131219820Sjeff cl_timer_start(&trans_mgr_p->madw_list_timer, 132219820Sjeff p_vend->timeout); 133219820Sjeff 134219820Sjeff /* go to the next object and check if it also needs to be removed - didn't receive response */ 135219820Sjeff /* we need to do it before we move current item to the end of the list */ 136219820Sjeff p_list_next_item = cl_qlist_next(p_list_item); 137219820Sjeff 138219820Sjeff /* remove from the head */ 139219820Sjeff cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p, 140219820Sjeff &(osm_madw_req_p->list_item)); 141219820Sjeff 142219820Sjeff /* insert the object to the qlist and the qmap */ 143219820Sjeff cl_qlist_insert_tail(trans_mgr_p->madw_reqs_list_p, 144219820Sjeff &(osm_madw_req_p->list_item)); 145219820Sjeff 146219820Sjeff } else { 147219820Sjeff /* go to the next object and check if it also needs to be removed - didn't receive response */ 148219820Sjeff p_list_next_item = cl_qlist_next(p_list_item); 149219820Sjeff 150219820Sjeff /* remove from the head */ 151219820Sjeff cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p, 152219820Sjeff &(osm_madw_req_p->list_item)); 153219820Sjeff 154219820Sjeff /* add it to the tmp_madw_p_list to be removed */ 155219820Sjeff cl_list_insert_tail(&tmp_madw_p_list, 156219820Sjeff osm_madw_req_p->p_madw); 157219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 158219820Sjeff "__osm_transaction_mgr_callback : Found failed transaction madw: %p\n", 159219820Sjeff osm_madw_req_p->p_madw); 160219820Sjeff } 161219820Sjeff 162219820Sjeff /* Advance */ 163219820Sjeff p_list_item = p_list_next_item; 164219820Sjeff if (p_list_item == cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) { 165219820Sjeff /* the list is empty - nothing to do */ 166219820Sjeff break; 167219820Sjeff } 168219820Sjeff 169219820Sjeff /* get the osm_madw_req_p */ 170219820Sjeff osm_madw_req_p = 171219820Sjeff PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item); 172219820Sjeff } 173219820Sjeff 174219820Sjeff /* look at the current p_list_item. If it is not the end item - then we need to */ 175219820Sjeff /* re-start the timer */ 176219820Sjeff if (p_list_item != cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) { 177219820Sjeff /* get the osm_madw_req_p */ 178219820Sjeff osm_madw_req_p = 179219820Sjeff PARENT_STRUCT(p_list_item, osm_madw_req_t, list_item); 180219820Sjeff 181219820Sjeff /* we have the object that still didn't get response - re-start the timer */ 182219820Sjeff /* start the timer to the timeout (in miliseconds) */ 183219820Sjeff new_timeout = 184219820Sjeff (osm_madw_req_p->waking_time - cl_get_time_stamp()) / 1000 + 185219820Sjeff 1; 186219820Sjeff cl_status = 187219820Sjeff cl_timer_start(&trans_mgr_p->madw_list_timer, new_timeout); 188219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 189219820Sjeff "__osm_transaction_mgr_callback : Timer restart:%u\n", 190219820Sjeff new_timeout); 191219820Sjeff 192219820Sjeff if (cl_status != CL_SUCCESS) { 193219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 194219820Sjeff "__osm_transaction_mgr_callback : ERROR 1000: " 195219820Sjeff "Failed to start timer\n"); 196219820Sjeff } 197219820Sjeff } 198219820Sjeff /* if not empty - retry on retry list: */ 199219820Sjeff if (!cl_is_list_empty(&retry_madw_p_list)) { 200219820Sjeff 201219820Sjeff /* remove all elements that were retried: */ 202219820Sjeff osm_madw_req_p = 203219820Sjeff (osm_madw_req_t 204219820Sjeff *) (cl_list_remove_head(&retry_madw_p_list)); 205219820Sjeff while (osm_madw_req_p != NULL) { 206219820Sjeff 207219820Sjeff /* resend: */ 208219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 209219820Sjeff "__osm_transaction_mgr_callback : " 210219820Sjeff "Retry %d of madw %p\n", 211219820Sjeff OSM_DEFAULT_RETRY_COUNT - 212219820Sjeff osm_madw_req_p->retry_cnt, 213219820Sjeff osm_madw_req_p->p_madw); 214219820Sjeff 215219820Sjeff /* actually send it */ 216219820Sjeff#ifdef OSM_VENDOR_INTF_MTL 217219820Sjeff osm_mtl_send_mad((osm_mtl_bind_info_t *) 218219820Sjeff osm_madw_req_p->p_bind, 219219820Sjeff osm_madw_req_p->p_madw); 220219820Sjeff#else 221219820Sjeff ib_api_status_t 222219820Sjeff osm_ts_send_mad(osm_ts_bind_info_t * p_bind, 223219820Sjeff osm_madw_t * const p_madw); 224219820Sjeff osm_ts_send_mad((osm_ts_bind_info_t *) osm_madw_req_p-> 225219820Sjeff p_bind, osm_madw_req_p->p_madw); 226219820Sjeff#endif 227219820Sjeff /* next one */ 228219820Sjeff osm_madw_req_p = 229219820Sjeff (osm_madw_req_t 230219820Sjeff *) (cl_list_remove_head(&retry_madw_p_list)); 231219820Sjeff } 232219820Sjeff } 233219820Sjeff 234219820Sjeff /* if the tmp_madw_p_list has elements - need to call the send_err_callback */ 235219820Sjeff madw_p = (osm_madw_t *) (cl_list_remove_head(&tmp_madw_p_list)); 236219820Sjeff while (madw_p != NULL) { 237219820Sjeff /* need to remove it from pool */ 238219820Sjeff 239219820Sjeff /* obtain the madw_p stored as the wrid in the send call */ 240219820Sjeff p_mad = osm_madw_get_mad_ptr(madw_p); 241219820Sjeff p_bind = madw_p->h_bind; 242219820Sjeff /* 243219820Sjeff Return any wrappers to the pool that may have been 244219820Sjeff pre-emptively allocated to handle a receive. 245219820Sjeff */ 246219820Sjeff if (madw_p->vend_wrap.p_resp_madw) { 247219820Sjeff#ifdef OSM_VENDOR_INTF_MTL 248219820Sjeff osm_mad_pool_put(p_bind->p_osm_pool, 249219820Sjeff madw_p->vend_wrap.p_resp_madw); 250219820Sjeff#else 251219820Sjeff osm_mad_pool_put(p_bind->p_osm_pool, 252219820Sjeff madw_p->vend_wrap.p_resp_madw); 253219820Sjeff#endif 254219820Sjeff madw_p->vend_wrap.p_resp_madw = NULL; 255219820Sjeff } 256219820Sjeff 257219820Sjeff /* invoke the CB */ 258219820Sjeff (*(osm_vend_mad_send_err_callback_t) 259219820Sjeff (p_bind->send_err_callback)) (p_bind->client_context, madw_p); 260219820Sjeff madw_p = (osm_madw_t *) (cl_list_remove_head(&tmp_madw_p_list)); 261219820Sjeff } 262219820Sjeff 263219820SjeffExit: 264219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 265219820Sjeff 266219820Sjeff} 267219820Sjeff 268219820Sjeff/* 269219820Sjeff * Construct and Initialize 270219820Sjeff */ 271219820Sjeff 272219820Sjeffvoid osm_transaction_mgr_init(IN osm_vendor_t * const p_vend) 273219820Sjeff{ 274219820Sjeff cl_status_t cl_status; 275219820Sjeff osm_transaction_mgr_t *trans_mgr_p; 276219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 277219820Sjeff 278219820Sjeff CL_ASSERT(p_vend->p_transaction_mgr == NULL); 279219820Sjeff 280219820Sjeff (osm_transaction_mgr_t *) p_vend->p_transaction_mgr = 281219820Sjeff (osm_transaction_mgr_t *) malloc(sizeof(osm_transaction_mgr_t)); 282219820Sjeff 283219820Sjeff trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr; 284219820Sjeff 285219820Sjeff /* construct lock object */ 286219820Sjeff cl_spinlock_construct(&(trans_mgr_p->transaction_mgr_lock)); 287219820Sjeff CL_ASSERT(cl_spinlock_init(&(trans_mgr_p->transaction_mgr_lock)) == 288219820Sjeff CL_SUCCESS); 289219820Sjeff 290219820Sjeff /* initialize the qlist */ 291219820Sjeff trans_mgr_p->madw_reqs_list_p = 292219820Sjeff (cl_qlist_t *) malloc(sizeof(cl_qlist_t)); 293219820Sjeff cl_qlist_init(trans_mgr_p->madw_reqs_list_p); 294219820Sjeff 295219820Sjeff /* initialize the qmap */ 296219820Sjeff trans_mgr_p->madw_by_tid_map_p = 297219820Sjeff (cl_qmap_t *) malloc(sizeof(cl_qmap_t)); 298219820Sjeff cl_qmap_init(trans_mgr_p->madw_by_tid_map_p); 299219820Sjeff 300219820Sjeff /* create the timer used by the madw_req_list */ 301219820Sjeff cl_timer_construct(&(trans_mgr_p->madw_list_timer)); 302219820Sjeff 303219820Sjeff /* init the timer with timeout. */ 304219820Sjeff cl_status = cl_timer_init(&trans_mgr_p->madw_list_timer, 305219820Sjeff __osm_transaction_mgr_callback, p_vend); 306219820Sjeff 307219820Sjeff if (cl_status != CL_SUCCESS) { 308219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 309219820Sjeff "osm_transaction_mgr_init : ERROR 1000: " 310219820Sjeff "Failed to initialize madw_reqs_list timer\n"); 311219820Sjeff } 312219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 313219820Sjeff} 314219820Sjeff 315219820Sjeffvoid osm_transaction_mgr_destroy(IN osm_vendor_t * const p_vend) 316219820Sjeff{ 317219820Sjeff osm_transaction_mgr_t *trans_mgr_p; 318219820Sjeff cl_list_item_t *p_list_item; 319219820Sjeff cl_map_item_t *p_map_item; 320219820Sjeff osm_madw_req_t *osm_madw_req_p; 321219820Sjeff 322219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 323219820Sjeff 324219820Sjeff trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr; 325219820Sjeff 326219820Sjeff if (p_vend->p_transaction_mgr != NULL) { 327219820Sjeff /* we need to get a lock */ 328219820Sjeff cl_spinlock_acquire(&trans_mgr_p->transaction_mgr_lock); 329219820Sjeff 330219820Sjeff /* go over all the items in the list and remove them */ 331219820Sjeff p_list_item = 332219820Sjeff cl_qlist_remove_head(trans_mgr_p->madw_reqs_list_p); 333219820Sjeff while (p_list_item != 334219820Sjeff cl_qlist_end(trans_mgr_p->madw_reqs_list_p)) { 335219820Sjeff osm_madw_req_p = (osm_madw_req_t *) p_list_item; 336219820Sjeff 337219820Sjeff if (osm_madw_req_p->p_madw->p_mad) 338219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 339219820Sjeff "osm_transaction_mgr_destroy: " 340219820Sjeff "Found outstanding MADW:%p TID:<0x%" 341219820Sjeff PRIx64 ">.\n", osm_madw_req_p->p_madw, 342219820Sjeff osm_madw_req_p->p_madw->p_mad-> 343219820Sjeff trans_id); 344219820Sjeff else 345219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 346219820Sjeff "osm_transaction_mgr_destroy: " 347219820Sjeff "Found outstanding MADW:%p TID:UNDEFINED.\n", 348219820Sjeff osm_madw_req_p->p_madw); 349219820Sjeff 350219820Sjeff /* each item - remove it from the map */ 351219820Sjeff p_map_item = &(osm_madw_req_p->map_item); 352219820Sjeff cl_qmap_remove_item(trans_mgr_p->madw_by_tid_map_p, 353219820Sjeff p_map_item); 354219820Sjeff /* free the item */ 355219820Sjeff free(osm_madw_req_p); 356219820Sjeff p_list_item = 357219820Sjeff cl_qlist_remove_head(trans_mgr_p->madw_reqs_list_p); 358219820Sjeff } 359219820Sjeff /* free the qlist and qmap */ 360219820Sjeff free(trans_mgr_p->madw_reqs_list_p); 361219820Sjeff free(trans_mgr_p->madw_by_tid_map_p); 362219820Sjeff /* reliease and destroy the lock */ 363219820Sjeff cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock); 364219820Sjeff cl_spinlock_destroy(&(trans_mgr_p->transaction_mgr_lock)); 365219820Sjeff /* destroy the timer */ 366219820Sjeff cl_timer_trim(&trans_mgr_p->madw_list_timer, 1); 367219820Sjeff cl_timer_destroy(&trans_mgr_p->madw_list_timer); 368219820Sjeff /* free the transaction_manager object */ 369219820Sjeff free(trans_mgr_p); 370219820Sjeff trans_mgr_p = NULL; 371219820Sjeff } 372219820Sjeff 373219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 374219820Sjeff} 375219820Sjeff 376219820Sjeffib_api_status_t 377219820Sjeffosm_transaction_mgr_insert_madw(IN osm_bind_handle_t * const p_bind, 378219820Sjeff IN osm_madw_t * p_madw) 379219820Sjeff{ 380219820Sjeff#ifdef OSM_VENDOR_INTF_MTL 381219820Sjeff osm_vendor_t *const p_vend = ((osm_mtl_bind_info_t *) p_bind)->p_vend; 382219820Sjeff#else 383219820Sjeff osm_vendor_t *const p_vend = ((osm_ts_bind_info_t *) p_bind)->p_vend; 384219820Sjeff#endif 385219820Sjeff osm_transaction_mgr_t *trans_mgr_p; 386219820Sjeff osm_madw_req_t *osm_madw_req_p; 387219820Sjeff uint64_t timeout; 388219820Sjeff uint64_t waking_time; 389219820Sjeff cl_status_t cl_status; 390219820Sjeff uint64_t key; 391219820Sjeff const ib_mad_t *mad_p = p_madw->p_mad; 392219820Sjeff 393219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 394219820Sjeff 395219820Sjeff CL_ASSERT(mad_p); 396219820Sjeff 397219820Sjeff trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr; 398219820Sjeff 399219820Sjeff timeout = (uint64_t) (p_vend->timeout) * 1000; /* change the miliseconds value of timeout to microseconds. */ 400219820Sjeff waking_time = timeout + cl_get_time_stamp(); 401219820Sjeff 402219820Sjeff osm_madw_req_p = (osm_madw_req_t *) malloc(sizeof(osm_madw_req_t)); 403219820Sjeff 404219820Sjeff osm_madw_req_p->p_madw = p_madw; 405219820Sjeff osm_madw_req_p->waking_time = waking_time; 406219820Sjeff osm_madw_req_p->retry_cnt = OSM_DEFAULT_RETRY_COUNT; 407219820Sjeff osm_madw_req_p->p_bind = p_bind; 408219820Sjeff 409219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 410219820Sjeff "osm_transaction_mgr_insert_madw: " 411219820Sjeff "Inserting MADW:%p with waking_time: <0x%" PRIx64 "> TID:<0x%" 412219820Sjeff PRIx64 ">.\n", p_madw, waking_time, p_madw->p_mad->trans_id); 413219820Sjeff 414219820Sjeff /* Get the lock on the manager */ 415219820Sjeff cl_spinlock_acquire(&(trans_mgr_p->transaction_mgr_lock)); 416219820Sjeff /* If the list is empty - need to start the timer with timer of timeout (in miliseconds) */ 417219820Sjeff if (cl_is_qlist_empty(trans_mgr_p->madw_reqs_list_p)) { 418219820Sjeff /* stop the timer if it is running */ 419219820Sjeff cl_timer_stop(&trans_mgr_p->madw_list_timer); 420219820Sjeff 421219820Sjeff /* start the timer to the timeout (in miliseconds) */ 422219820Sjeff cl_status = cl_timer_start(&trans_mgr_p->madw_list_timer, 423219820Sjeff p_vend->timeout); 424219820Sjeff if (cl_status != CL_SUCCESS) { 425219820Sjeff osm_log(p_vend->p_log, OSM_LOG_ERROR, 426219820Sjeff "osm_transaction_mgr_insert_madw : ERROR 1000: " 427219820Sjeff "Failed to start timer\n"); 428219820Sjeff } 429219820Sjeff } 430219820Sjeff 431219820Sjeff /* insert the object to the qlist and the qmap */ 432219820Sjeff cl_qlist_insert_tail(trans_mgr_p->madw_reqs_list_p, 433219820Sjeff &(osm_madw_req_p->list_item)); 434219820Sjeff /* get the key */ 435219820Sjeff key = (uint64_t) mad_p->trans_id; 436219820Sjeff cl_qmap_insert(trans_mgr_p->madw_by_tid_map_p, key, 437219820Sjeff &(osm_madw_req_p->map_item)); 438219820Sjeff cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock); 439219820Sjeff 440219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 441219820Sjeff 442219820Sjeff return (IB_SUCCESS); 443219820Sjeff} 444219820Sjeff 445219820Sjeffib_api_status_t 446219820Sjeffosm_transaction_mgr_erase_madw(IN osm_vendor_t * const p_vend, 447219820Sjeff IN ib_mad_t * p_mad) 448219820Sjeff{ 449219820Sjeff osm_transaction_mgr_t *trans_mgr_p; 450219820Sjeff osm_madw_req_t *osm_madw_req_p; 451219820Sjeff uint64_t key; 452219820Sjeff cl_map_item_t *p_map_item; 453219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 454219820Sjeff 455219820Sjeff trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr; 456219820Sjeff 457219820Sjeff key = (uint64_t) p_mad->trans_id; 458219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 459219820Sjeff "osm_transaction_mgr_erase_madw: " 460219820Sjeff "Removing TID:<0x%" PRIx64 ">.\n", p_mad->trans_id); 461219820Sjeff 462219820Sjeff cl_spinlock_acquire(&trans_mgr_p->transaction_mgr_lock); 463219820Sjeff p_map_item = cl_qmap_get(trans_mgr_p->madw_by_tid_map_p, key); 464219820Sjeff if (p_map_item != cl_qmap_end(trans_mgr_p->madw_by_tid_map_p)) { 465219820Sjeff /* we found such an item. */ 466219820Sjeff /* get the osm_madw_req_p */ 467219820Sjeff osm_madw_req_p = 468219820Sjeff PARENT_STRUCT(p_map_item, osm_madw_req_t, map_item); 469219820Sjeff 470219820Sjeff /* remove the item from the qlist */ 471219820Sjeff cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p, 472219820Sjeff &(osm_madw_req_p->list_item)); 473219820Sjeff /* remove the item from the qmap */ 474219820Sjeff cl_qmap_remove_item(trans_mgr_p->madw_by_tid_map_p, 475219820Sjeff &(osm_madw_req_p->map_item)); 476219820Sjeff 477219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 478219820Sjeff "osm_transaction_mgr_erase_madw: " 479219820Sjeff "Removed TID:<0x%" PRIx64 ">.\n", p_mad->trans_id); 480219820Sjeff 481219820Sjeff /* free the item */ 482219820Sjeff free(osm_madw_req_p); 483219820Sjeff } else { 484219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 485219820Sjeff "osm_transaction_mgr_erase_madw: " 486219820Sjeff "osm_transaction_mgr_erase_madw:<0x%" PRIx64 487219820Sjeff "> NOT FOUND.\n", p_mad->trans_id); 488219820Sjeff } 489219820Sjeff cl_spinlock_release(&trans_mgr_p->transaction_mgr_lock); 490219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 491219820Sjeff 492219820Sjeff return (IB_SUCCESS); 493219820Sjeff} 494219820Sjeff 495219820Sjeffib_api_status_t 496219820Sjeffosm_transaction_mgr_get_madw_for_tid(IN osm_vendor_t * const p_vend, 497219820Sjeff IN ib_mad_t * const p_mad, 498219820Sjeff OUT osm_madw_t ** req_madw_p) 499219820Sjeff{ 500219820Sjeff osm_transaction_mgr_t *trans_mgr_p; 501219820Sjeff osm_madw_req_t *osm_madw_req_p; 502219820Sjeff cl_map_item_t *p_map_item; 503219820Sjeff uint64_t key; 504219820Sjeff OSM_LOG_ENTER(p_vend->p_log); 505219820Sjeff 506219820Sjeff trans_mgr_p = (osm_transaction_mgr_t *) p_vend->p_transaction_mgr; 507219820Sjeff 508219820Sjeff *req_madw_p = NULL; 509219820Sjeff 510219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 511219820Sjeff "osm_transaction_mgr_get_madw_for_tid: " 512219820Sjeff "Looking for TID:<0x%" PRIx64 ">.\n", p_mad->trans_id); 513219820Sjeff 514219820Sjeff key = (uint64_t) p_mad->trans_id; 515219820Sjeff cl_spinlock_acquire(&(trans_mgr_p->transaction_mgr_lock)); 516219820Sjeff p_map_item = cl_qmap_get(trans_mgr_p->madw_by_tid_map_p, key); 517219820Sjeff if (p_map_item != cl_qmap_end(trans_mgr_p->madw_by_tid_map_p)) { 518219820Sjeff /* we found such an item. */ 519219820Sjeff /* get the osm_madw_req_p */ 520219820Sjeff osm_madw_req_p = 521219820Sjeff PARENT_STRUCT(p_map_item, osm_madw_req_t, map_item); 522219820Sjeff 523219820Sjeff /* Since the Transaction was looked up and provided for */ 524219820Sjeff /* processing we retire it */ 525219820Sjeff cl_qlist_remove_item(trans_mgr_p->madw_reqs_list_p, 526219820Sjeff &(osm_madw_req_p->list_item)); 527219820Sjeff /* remove the item from the qmap */ 528219820Sjeff cl_qmap_remove_item(trans_mgr_p->madw_by_tid_map_p, 529219820Sjeff &(osm_madw_req_p->map_item)); 530219820Sjeff 531219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 532219820Sjeff "osm_transaction_mgr_get_madw_for_tid: " 533219820Sjeff "Removed TID:<0x%" PRIx64 ">.\n", p_mad->trans_id); 534219820Sjeff 535219820Sjeff *req_madw_p = osm_madw_req_p->p_madw; 536219820Sjeff } 537219820Sjeff 538219820Sjeff cl_spinlock_release(&(trans_mgr_p->transaction_mgr_lock)); 539219820Sjeff osm_log(p_vend->p_log, OSM_LOG_DEBUG, 540219820Sjeff "osm_transaction_mgr_get_madw_for_tid: " 541219820Sjeff "Got MADW:%p.\n", *req_madw_p); 542219820Sjeff OSM_LOG_EXIT(p_vend->p_log); 543219820Sjeff return (IB_SUCCESS); 544219820Sjeff} 545219820Sjeff 546219820Sjeff#endif 547