Status_t sa_SMInfoRecord(Mai_t *maip, sa_cntxt_t* sa_cntxt) { uint32_t records; uint16_t attribOffset; IB_ENTER("sa_SMInfoRecord", maip, 0, 0, 0); // // Assume failure. // records = 0; // // Check the method. If this is a template lookup, then call the regular // GetTable(*) template lookup routine. // switch (maip->base.method) { case SA_CM_GET: INCREMENT_COUNTER(smCounterSaRxGetSmInfoRecord); (void)sa_SMInfoRecord_GetTable(maip, &records); break; case SA_CM_GETTABLE: INCREMENT_COUNTER(smCounterSaRxGetTblSmInfoRecord); (void)sa_SMInfoRecord_GetTable(maip, &records); break; default: maip->base.status = MAD_STATUS_BAD_METHOD; (void)sa_send_reply(maip, sa_cntxt); IB_LOG_WARN("sa_SMInfoRecord: invalid METHOD:", maip->base.method); IB_EXIT("sa_SMInfoRecord", VSTATUS_OK); return(VSTATUS_OK); break; } // // Determine reply status // if (records == 0) { maip->base.status = MAD_STATUS_SA_NO_RECORDS; } else if ((maip->base.method == SA_CM_GET) && (records != 1)) { IB_LOG_WARN("sa_SMInfoRecord: too many records for SA_CM_GET:", records); records = 0; maip->base.status = MAD_STATUS_SA_TOO_MANY_RECS; } else { maip->base.status = MAD_STATUS_OK; } attribOffset = sizeof(STL_SMINFO_RECORD) + Calculate_Padding(sizeof(STL_SMINFO_RECORD)); /* setup attribute offset for possible RMPP transfer */ sa_cntxt->attribLen = attribOffset; sa_cntxt_data( sa_cntxt, sa_data, records * attribOffset); (void)sa_send_reply(maip, sa_cntxt ); IB_EXIT("sa_SMInfoRecord", VSTATUS_OK); return(VSTATUS_OK); }
// Wraps setup of SA Context when caching is available. Simply delegates to // sa_cntxt_data if the cache is not valid. // Status_t sa_cntxt_data_cached(sa_cntxt_t* sa_cntxt, void* buf, uint32_t len, SACacheEntry_t *cache) { IB_ENTER("sa_cntxt_data_cached", sa_cntxt, buf, len, cache); if (!cache || !cache->valid) { // normal non-cached transfer sa_cntxt_data(sa_cntxt, buf, len); } else if (cache->transient) { // transient; the cache was built on the fly and should be copied. the // context can take care of deallocation sa_cntxt_data(sa_cntxt, cache->data, cache->len); } else { // cached transfer; just point the SA context to the cache buffer sa_cntxt->data = (char*)cache->data; sa_cntxt->len = cache->len; sa_cntxt->cache = cache; // use the cache-enabled free function sa_cntxt->freeDataFunc = sa_cache_cntxt_free; } IB_EXIT("sa_cntxt_data_cached", VSTATUS_OK); return VSTATUS_OK; }
Status_t sa_ClassPortInfo(Mai_t *maip, sa_cntxt_t* sa_cntxt) { uint16_t attribOffset; union { STL_CLASS_PORT_INFO stl_version; IB_CLASS_PORT_INFO ib_version; } myCPI; IB_ENTER("sa_ClassPortInfo", maip, 0, 0, 0); // // Check the method. For ClassPortInfo, you can only do a Get(). // if (maip->base.method == SA_CM_GET) { INCREMENT_COUNTER(smCounterSaRxGetClassPortInfo); if (maip->base.cversion == SA_MAD_CVERSION) { memset(&myCPI.ib_version,0,sizeof(IB_CLASS_PORT_INFO)); myCPI.ib_version.BaseVersion = saClassPortInfo.BaseVersion; myCPI.ib_version.ClassVersion = saClassPortInfo.ClassVersion; myCPI.ib_version.CapMask = STL_CLASS_PORT_CAPMASK_CM2 | STL_SA_CAPABILITY_MULTICAST_SUPPORT | STL_SA_CAPABILITY_MULTIPATH_SUPPORT | STL_SA_CAPABILITY_PORTINFO_CAPMASK_MATCH | STL_SA_CAPABILITY_PA_SERVICES_SUPPORT; myCPI.ib_version.u1.s.CapMask2 = STL_SA_CAPABILITY2_QOS_SUPPORT | STL_SA_CAPABILITY2_MFTTOP_SUPPORT | STL_SA_CAPABILITY2_FULL_PORTINFO | STL_SA_CAPABILITY2_EXT_SUPPORT; myCPI.ib_version.u1.s.RespTimeValue = saClassPortInfo.u1.s.RespTimeValue; myCPI.ib_version.u3.s.RedirectQP = saClassPortInfo.u3.s.RedirectQP; myCPI.ib_version.u5.s.TrapHopLimit = saClassPortInfo.u5.s.TrapHopLimit; myCPI.ib_version.u5.s.TrapQP = saClassPortInfo.u5.s.TrapQP; BSWAP_IB_CLASS_PORT_INFO(&myCPI.ib_version); attribOffset = sizeof(IB_CLASS_PORT_INFO) + Calculate_Padding(sizeof(IB_CLASS_PORT_INFO)); sa_cntxt_data( sa_cntxt, &myCPI.ib_version, attribOffset); sa_cntxt->attribLen = attribOffset; maip->base.status = MAD_STATUS_OK; } else if (maip->base.cversion >= STL_SM_CLASS_VERSION) { myCPI.stl_version = saClassPortInfo; BSWAP_STL_CLASS_PORT_INFO(&myCPI.stl_version); attribOffset = sizeof(STL_CLASS_PORT_INFO) + Calculate_Padding(sizeof(STL_CLASS_PORT_INFO)); sa_cntxt_data( sa_cntxt, &myCPI.stl_version, attribOffset); sa_cntxt->attribLen = attribOffset; maip->base.status = MAD_STATUS_OK; } else { maip->base.status = MAD_STATUS_BAD_METHOD; } } else { maip->base.status = MAD_STATUS_BAD_METHOD; } (void)sa_send_reply(maip, sa_cntxt); IB_EXIT("sa_ClassPortInfo", VSTATUS_OK); return(VSTATUS_OK); }