void __mad_recv_processor(IN void *context) { mad_bind_info_t *p_mad_bind_info = (mad_bind_info_t *) context; umadt_obj_t *p_umadt_obj; osm_madw_t *p_osm_madw = NULL; osm_vend_wrap_t *p_vend_wrap = NULL; osm_mad_addr_t osm_mad_addr = { 0 }; cl_list_item_t *p_list_item; void *transaction_context; FSTATUS Status; MadtStruct *pRecvMad = NULL; MadWorkCompletion *pRecvCmp = NULL; CL_ASSERT(context); p_mad_bind_info = (mad_bind_info_t *) context; p_umadt_obj = p_mad_bind_info->p_umadt_obj; /* PollFor a completion */ /* if FNOTFOND, then wait for a completion then again poll and return the MAD */ while (1) { Status = p_umadt_obj->uMadtInterface. uMadtPollForRecvCompletion(p_mad_bind_info->umadt_handle, &pRecvMad, &pRecvCmp); if (Status != FSUCCESS) { if (Status == FNOT_FOUND) { /* Wait for a completion */ Status = p_umadt_obj->uMadtInterface.uMadtWaitForAnyCompletion(p_mad_bind_info->umadt_handle, RECV_COMPLETION, 0x5000); /* 5 sec timeout */ if (Status == FTIMEOUT) { continue; } CL_ASSERT(Status == FSUCCESS); Status = p_umadt_obj->uMadtInterface. uMadtPollForRecvCompletion(p_mad_bind_info-> umadt_handle, &pRecvMad, &pRecvCmp); if (Status != FSUCCESS) { printf (" mad_recv_worker: Error in PollForRecv returning <%x>\n", Status); CL_ASSERT(0); } } else { printf ("uMadtPollForRecvCompletion Status=<%x>\n", Status); CL_ASSERT(0); } } CL_ASSERT(pRecvMad); CL_ASSERT(pRecvCmp); if (((ib_sa_mad_t_vM3 *) (&pRecvMad->IBMad))->frag_flag & 0x20) { /* Ignore the ACK packet */ Status = p_umadt_obj->uMadtInterface. uMadtReleaseRecvMad(p_mad_bind_info->umadt_handle, pRecvMad); continue; } /* */ /* Extract the return address to pass it on to the client */ /* */ osm_mad_addr.dest_lid = pRecvCmp->AddressInfo.DestLid; osm_mad_addr.path_bits = pRecvCmp->AddressInfo.PathBits; osm_mad_addr.static_rate = pRecvCmp->AddressInfo.StaticRate; if (p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_LID || p_mad_bind_info->umadt_reg_class.ClassId == IB_MCLASS_SUBN_DIR) { osm_mad_addr.addr_type.smi.source_lid = pRecvCmp->AddressInfo.AddrType.Smi.SourceLid; /* osm_mad_addr.addr_type.smi.port_num = pRecvCmp->AddressInfo.AddrType.Smi.PortNumber; */ } else { osm_mad_addr.addr_type.gsi.remote_qp = pRecvCmp->AddressInfo.AddrType.Gsi.RemoteQpNumber; osm_mad_addr.addr_type.gsi.remote_qkey = pRecvCmp->AddressInfo.AddrType.Gsi.RemoteQkey; osm_mad_addr.addr_type.gsi.pkey_ix = 0; osm_mad_addr.addr_type.gsi.service_level = pRecvCmp->AddressInfo.AddrType.Gsi.ServiceLevel; osm_mad_addr.addr_type.gsi.global_route = pRecvCmp->AddressInfo.AddrType.Gsi.GlobalRoute; /* osm_mad_addr.addr_type.gsi.grh_info = pRecvCmp->AddressInfo.AddrType.Gsi.GRHInfo; */ } p_osm_madw = osm_mad_pool_get_wrapper(p_mad_bind_info->p_mad_pool, p_mad_bind_info, MAD_BLOCK_SIZE, (ib_mad_t *) & pRecvMad->IBMad, &osm_mad_addr); CL_ASSERT(p_osm_madw); p_vend_wrap = osm_madw_get_vend_ptr(p_osm_madw); CL_ASSERT(p_vend_wrap); p_vend_wrap->p_madt_struct = pRecvMad; p_vend_wrap->direction = RECEIVE; osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG, "__mad_recv_processor: " "Received data p_osm_madw[0x%p].\n", p_osm_madw); /* */ /* Do TID Processing. */ /* */ /* If R bit is set swap the TID */ cl_spinlock_acquire(&p_mad_bind_info->trans_ctxt_lock); p_list_item = cl_qlist_find_from_head(&p_mad_bind_info->trans_ctxt_list, __match_tid_context, &p_osm_madw->p_mad->trans_id); if (p_list_item == cl_qlist_end(&p_mad_bind_info->trans_ctxt_list)) { transaction_context = NULL; } else { transaction_context = ((trans_context_t *) p_list_item)->context; cl_qlist_remove_item(&p_mad_bind_info->trans_ctxt_list, p_list_item); free(p_list_item); } cl_spinlock_release(&p_mad_bind_info->trans_ctxt_lock); ((ib_mad_t *) p_osm_madw->p_mad)->trans_id = cl_ntoh64(p_osm_madw->p_mad->trans_id >> 24); osm_log(p_mad_bind_info->p_umadt_obj->p_log, OSM_LOG_DEBUG, "__mad_recv_processor: " "Received data p_osm_madw [0x%p]" "\n\t\t\t\tTID[0x%" PRIx64 ", context[%p]. \n", p_osm_madw, ((ib_mad_t *) p_osm_madw->p_mad)->trans_id, transaction_context); (*(p_mad_bind_info->mad_recv_callback)) (p_osm_madw, p_mad_bind_info-> client_context, transaction_context); } }
static void __osm_al_rcv_callback(IN void *mad_svc_context, IN ib_mad_element_t * p_elem) { osm_al_bind_info_t *const p_bind = (osm_al_bind_info_t *) mad_svc_context; osm_vendor_t *const p_vend = p_bind->p_vend; osm_madw_t *p_old_madw; osm_madw_t *p_new_madw; osm_vend_wrap_t *p_old_vw; osm_vend_wrap_t *p_new_vw; ib_mad_t *p_new_mad; osm_mad_addr_t mad_addr; OSM_LOG_ENTER(p_vend->p_log); CL_ASSERT(p_elem->context1 == NULL); CL_ASSERT(p_elem->context2 == NULL); p_new_mad = ib_get_mad_buf(p_elem); /* In preperation for initializing the new mad wrapper, Initialize the mad_addr structure for the received wire MAD. */ mad_addr.dest_lid = p_elem->remote_lid; mad_addr.path_bits = p_elem->path_bits; /* TO DO - figure out which #define to use for the 2.5 Gb rate... */ mad_addr.static_rate = 0; if (p_new_mad->mgmt_class == IB_MCLASS_SUBN_LID || p_new_mad->mgmt_class == IB_MCLASS_SUBN_DIR) { mad_addr.addr_type.smi.source_lid = p_elem->remote_lid; } else { mad_addr.addr_type.gsi.remote_qp = p_elem->remote_qp; mad_addr.addr_type.gsi.remote_qkey = p_elem->remote_qkey; mad_addr.addr_type.gsi.pkey_ix = p_elem->pkey_index; mad_addr.addr_type.gsi.service_level = p_elem->remote_sl; mad_addr.addr_type.gsi.global_route = FALSE; } /* If this MAD is a response to a previous request, then grab our pre-allocated MAD wrapper. Otherwise, allocate a new MAD wrapper. */ if (ib_mad_is_response(p_new_mad)) { CL_ASSERT(p_elem->send_context1 != NULL); CL_ASSERT(p_elem->send_context2 == NULL); p_old_madw = (osm_madw_t *) p_elem->send_context1; p_old_vw = osm_madw_get_vend_ptr(p_old_madw); p_new_madw = p_old_vw->p_resp_madw; CL_ASSERT(p_new_madw); osm_madw_init(p_new_madw, p_bind, p_elem->size, &mad_addr); osm_madw_set_mad(p_new_madw, p_new_mad); } else { CL_ASSERT(p_elem->send_context1 == NULL); CL_ASSERT(p_elem->send_context2 == NULL); p_new_madw = osm_mad_pool_get_wrapper(p_bind->p_osm_pool, p_bind, p_elem->size, p_new_mad, &mad_addr); } CL_ASSERT(p_new_madw); p_new_vw = osm_madw_get_vend_ptr(p_new_madw); p_new_vw->h_bind = p_bind; p_new_vw->size = p_elem->size; p_new_vw->p_elem = p_elem; p_new_vw->h_av = 0; p_new_vw->p_resp_madw = NULL; osm_log(p_vend->p_log, OSM_LOG_DEBUG, "__osm_al_rcv_callback: " "Calling receive callback function %p.\n", p_bind->rcv_callback); p_bind->rcv_callback(p_new_madw, p_bind->client_context, p_elem->send_context1); OSM_LOG_EXIT(p_vend->p_log); }