]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/ofed/management/opensm/opensm/osm_sa_portinfo_record.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / ofed / management / opensm / opensm / osm_sa_portinfo_record.c
1 /*
2  * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved.
4  * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
5  *
6  * This software is available to you under a choice of one of two
7  * licenses.  You may choose to be licensed under the terms of the GNU
8  * General Public License (GPL) Version 2, available from the file
9  * COPYING in the main directory of this source tree, or the
10  * OpenIB.org BSD license below:
11  *
12  *     Redistribution and use in source and binary forms, with or
13  *     without modification, are permitted provided that the following
14  *     conditions are met:
15  *
16  *      - Redistributions of source code must retain the above
17  *        copyright notice, this list of conditions and the following
18  *        disclaimer.
19  *
20  *      - Redistributions in binary form must reproduce the above
21  *        copyright notice, this list of conditions and the following
22  *        disclaimer in the documentation and/or other materials
23  *        provided with the distribution.
24  *
25  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32  * SOFTWARE.
33  *
34  */
35
36 /*
37  * Abstract:
38  *    Implementation of osm_pir_rcv_t.
39  * This object represents the PortInfoRecord Receiver object.
40  * This object is part of the opensm family of objects.
41  */
42
43 #if HAVE_CONFIG_H
44 #  include <config.h>
45 #endif                          /* HAVE_CONFIG_H */
46
47 #include <string.h>
48 #include <iba/ib_types.h>
49 #include <complib/cl_qmap.h>
50 #include <complib/cl_passivelock.h>
51 #include <complib/cl_debug.h>
52 #include <complib/cl_qlist.h>
53 #include <vendor/osm_vendor_api.h>
54 #include <opensm/osm_port.h>
55 #include <opensm/osm_node.h>
56 #include <opensm/osm_switch.h>
57 #include <opensm/osm_helper.h>
58 #include <opensm/osm_pkey.h>
59 #include <opensm/osm_sa.h>
60
61 typedef struct osm_pir_item {
62         cl_list_item_t list_item;
63         ib_portinfo_record_t rec;
64 } osm_pir_item_t;
65
66 typedef struct osm_pir_search_ctxt {
67         const ib_portinfo_record_t *p_rcvd_rec;
68         ib_net64_t comp_mask;
69         cl_qlist_t *p_list;
70         osm_sa_t *sa;
71         const osm_physp_t *p_req_physp;
72         boolean_t is_enhanced_comp_mask;
73 } osm_pir_search_ctxt_t;
74
75 /**********************************************************************
76  **********************************************************************/
77 static ib_api_status_t
78 __osm_pir_rcv_new_pir(IN osm_sa_t * sa,
79                       IN const osm_physp_t * const p_physp,
80                       IN cl_qlist_t * const p_list, IN ib_net16_t const lid)
81 {
82         osm_pir_item_t *p_rec_item;
83         ib_api_status_t status = IB_SUCCESS;
84
85         OSM_LOG_ENTER(sa->p_log);
86
87         p_rec_item = malloc(sizeof(*p_rec_item));
88         if (p_rec_item == NULL) {
89                 OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2102: "
90                         "rec_item alloc failed\n");
91                 status = IB_INSUFFICIENT_RESOURCES;
92                 goto Exit;
93         }
94
95         OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
96                 "New PortInfoRecord: port 0x%016" PRIx64
97                 ", lid %u, port %u\n",
98                 cl_ntoh64(osm_physp_get_port_guid(p_physp)),
99                 cl_ntoh16(lid), osm_physp_get_port_num(p_physp));
100
101         memset(p_rec_item, 0, sizeof(*p_rec_item));
102
103         p_rec_item->rec.lid = lid;
104         p_rec_item->rec.port_info = p_physp->port_info;
105         p_rec_item->rec.port_num = osm_physp_get_port_num(p_physp);
106
107         cl_qlist_insert_tail(p_list, &p_rec_item->list_item);
108
109 Exit:
110         OSM_LOG_EXIT(sa->p_log);
111         return (status);
112 }
113
114 /**********************************************************************
115  **********************************************************************/
116 static void
117 __osm_sa_pir_create(IN osm_sa_t * sa,
118                     IN const osm_physp_t * const p_physp,
119                     IN osm_pir_search_ctxt_t * const p_ctxt)
120 {
121         uint8_t lmc;
122         uint16_t max_lid_ho;
123         uint16_t base_lid_ho;
124         uint16_t match_lid_ho;
125         osm_physp_t *p_node_physp;
126
127         OSM_LOG_ENTER(sa->p_log);
128
129         if (p_physp->p_node->sw) {
130                 p_node_physp = osm_node_get_physp_ptr(p_physp->p_node, 0);
131                 base_lid_ho = cl_ntoh16(osm_physp_get_base_lid(p_node_physp));
132                 lmc =
133                     osm_switch_sp0_is_lmc_capable(p_physp->p_node->sw,
134                                                   sa->
135                                                   p_subn) ?
136                     osm_physp_get_lmc(p_node_physp) : 0;
137         } else {
138                 lmc = osm_physp_get_lmc(p_physp);
139                 base_lid_ho = cl_ntoh16(osm_physp_get_base_lid(p_physp));
140         }
141         max_lid_ho = (uint16_t) (base_lid_ho + (1 << lmc) - 1);
142
143         if (p_ctxt->comp_mask & IB_PIR_COMPMASK_LID) {
144                 match_lid_ho = cl_ntoh16(p_ctxt->p_rcvd_rec->lid);
145
146                 /*
147                    We validate that the lid belongs to this node.
148                  */
149                 OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
150                         "Comparing LID: %u <= %u <= %u\n",
151                         base_lid_ho, match_lid_ho, max_lid_ho);
152
153                 if (match_lid_ho < base_lid_ho || match_lid_ho > max_lid_ho)
154                         goto Exit;
155         }
156
157         __osm_pir_rcv_new_pir(sa, p_physp, p_ctxt->p_list,
158                               cl_hton16(base_lid_ho));
159
160 Exit:
161         OSM_LOG_EXIT(sa->p_log);
162 }
163
164 /**********************************************************************
165  **********************************************************************/
166 static void
167 __osm_sa_pir_check_physp(IN osm_sa_t * sa,
168                          IN const osm_physp_t * const p_physp,
169                          osm_pir_search_ctxt_t * const p_ctxt)
170 {
171         const ib_portinfo_record_t *p_rcvd_rec;
172         ib_net64_t comp_mask;
173         const ib_port_info_t *p_comp_pi;
174         const ib_port_info_t *p_pi;
175
176         OSM_LOG_ENTER(sa->p_log);
177
178         p_rcvd_rec = p_ctxt->p_rcvd_rec;
179         comp_mask = p_ctxt->comp_mask;
180         p_comp_pi = &p_rcvd_rec->port_info;
181         p_pi = &p_physp->port_info;
182
183         osm_dump_port_info(sa->p_log,
184                            osm_node_get_node_guid(p_physp->p_node),
185                            p_physp->port_guid,
186                            p_physp->port_num,
187                            &p_physp->port_info, OSM_LOG_DEBUG);
188
189         /* We have to re-check the base_lid, since if the given
190            base_lid in p_pi is zero - we are comparing on all ports. */
191         if (comp_mask & IB_PIR_COMPMASK_BASELID) {
192                 if (p_comp_pi->base_lid != p_pi->base_lid)
193                         goto Exit;
194         }
195         if (comp_mask & IB_PIR_COMPMASK_MKEY) {
196                 if (p_comp_pi->m_key != p_pi->m_key)
197                         goto Exit;
198         }
199         if (comp_mask & IB_PIR_COMPMASK_GIDPRE) {
200                 if (p_comp_pi->subnet_prefix != p_pi->subnet_prefix)
201                         goto Exit;
202         }
203         if (comp_mask & IB_PIR_COMPMASK_SMLID) {
204                 if (p_comp_pi->master_sm_base_lid != p_pi->master_sm_base_lid)
205                         goto Exit;
206         }
207
208         /* IBTA 1.2 errata provides support for bitwise compare if the bit 31
209            of the attribute modifier of the Get/GetTable is set */
210         if (comp_mask & IB_PIR_COMPMASK_CAPMASK) {
211                 if (p_ctxt->is_enhanced_comp_mask) {
212                         if (((p_comp_pi->capability_mask & p_pi->
213                               capability_mask) != p_comp_pi->capability_mask))
214                                 goto Exit;
215                 } else {
216                         if (p_comp_pi->capability_mask != p_pi->capability_mask)
217                                 goto Exit;
218                 }
219         }
220
221         if (comp_mask & IB_PIR_COMPMASK_DIAGCODE) {
222                 if (p_comp_pi->diag_code != p_pi->diag_code)
223                         goto Exit;
224         }
225         if (comp_mask & IB_PIR_COMPMASK_MKEYLEASEPRD) {
226                 if (p_comp_pi->m_key_lease_period != p_pi->m_key_lease_period)
227                         goto Exit;
228         }
229         if (comp_mask & IB_PIR_COMPMASK_LOCALPORTNUM) {
230                 if (p_comp_pi->local_port_num != p_pi->local_port_num)
231                         goto Exit;
232         }
233         if (comp_mask & IB_PIR_COMPMASK_LNKWIDTHSUPPORT) {
234                 if (p_comp_pi->link_width_supported !=
235                     p_pi->link_width_supported)
236                         goto Exit;
237         }
238         if (comp_mask & IB_PIR_COMPMASK_LNKWIDTHACTIVE) {
239                 if (p_comp_pi->link_width_active != p_pi->link_width_active)
240                         goto Exit;
241         }
242         if (comp_mask & IB_PIR_COMPMASK_LINKWIDTHENABLED) {
243                 if (p_comp_pi->link_width_enabled != p_pi->link_width_enabled)
244                         goto Exit;
245         }
246         if (comp_mask & IB_PIR_COMPMASK_LNKSPEEDSUPPORT) {
247                 if (ib_port_info_get_link_speed_sup(p_comp_pi) !=
248                     ib_port_info_get_link_speed_sup(p_pi))
249                         goto Exit;
250         }
251         if (comp_mask & IB_PIR_COMPMASK_PORTSTATE) {
252                 if (ib_port_info_get_port_state(p_comp_pi) !=
253                     ib_port_info_get_port_state(p_pi))
254                         goto Exit;
255         }
256         if (comp_mask & IB_PIR_COMPMASK_PORTPHYSTATE) {
257                 if (ib_port_info_get_port_phys_state(p_comp_pi) !=
258                     ib_port_info_get_port_phys_state(p_pi))
259                         goto Exit;
260         }
261         if (comp_mask & IB_PIR_COMPMASK_LINKDWNDFLTSTATE) {
262                 if (ib_port_info_get_link_down_def_state(p_comp_pi) !=
263                     ib_port_info_get_link_down_def_state(p_pi))
264                         goto Exit;
265         }
266         if (comp_mask & IB_PIR_COMPMASK_MKEYPROTBITS) {
267                 if (ib_port_info_get_mpb(p_comp_pi) !=
268                     ib_port_info_get_mpb(p_pi))
269                         goto Exit;
270         }
271         if (comp_mask & IB_PIR_COMPMASK_LMC) {
272                 if (ib_port_info_get_lmc(p_comp_pi) !=
273                     ib_port_info_get_lmc(p_pi))
274                         goto Exit;
275         }
276         if (comp_mask & IB_PIR_COMPMASK_LINKSPEEDACTIVE) {
277                 if (ib_port_info_get_link_speed_active(p_comp_pi) !=
278                     ib_port_info_get_link_speed_active(p_pi))
279                         goto Exit;
280         }
281         if (comp_mask & IB_PIR_COMPMASK_LINKSPEEDENABLE) {
282                 if (ib_port_info_get_link_speed_enabled(p_comp_pi) !=
283                     ib_port_info_get_link_speed_enabled(p_pi))
284                         goto Exit;
285         }
286         if (comp_mask & IB_PIR_COMPMASK_NEIGHBORMTU) {
287                 if (ib_port_info_get_neighbor_mtu(p_comp_pi) !=
288                     ib_port_info_get_neighbor_mtu(p_pi))
289                         goto Exit;
290         }
291         if (comp_mask & IB_PIR_COMPMASK_MASTERSMSL) {
292                 if (ib_port_info_get_master_smsl(p_comp_pi) !=
293                     ib_port_info_get_master_smsl(p_pi))
294                         goto Exit;
295         }
296         if (comp_mask & IB_PIR_COMPMASK_VLCAP) {
297                 if (ib_port_info_get_vl_cap(p_comp_pi) !=
298                     ib_port_info_get_vl_cap(p_pi))
299                         goto Exit;
300         }
301         if (comp_mask & IB_PIR_COMPMASK_INITTYPE) {
302                 if (ib_port_info_get_init_type(p_comp_pi) !=
303                     ib_port_info_get_init_type(p_pi))
304                         goto Exit;
305         }
306         if (comp_mask & IB_PIR_COMPMASK_VLHIGHLIMIT) {
307                 if (p_comp_pi->vl_high_limit != p_pi->vl_high_limit)
308                         goto Exit;
309         }
310         if (comp_mask & IB_PIR_COMPMASK_VLARBHIGHCAP) {
311                 if (p_comp_pi->vl_arb_high_cap != p_pi->vl_arb_high_cap)
312                         goto Exit;
313         }
314         if (comp_mask & IB_PIR_COMPMASK_VLARBLOWCAP) {
315                 if (p_comp_pi->vl_arb_low_cap != p_pi->vl_arb_low_cap)
316                         goto Exit;
317         }
318         if (comp_mask & IB_PIR_COMPMASK_MTUCAP) {
319                 if (ib_port_info_get_mtu_cap(p_comp_pi) !=
320                     ib_port_info_get_mtu_cap(p_pi))
321                         goto Exit;
322         }
323         if (comp_mask & IB_PIR_COMPMASK_VLSTALLCNT) {
324                 if (ib_port_info_get_vl_stall_count(p_comp_pi) !=
325                     ib_port_info_get_vl_stall_count(p_pi))
326                         goto Exit;
327         }
328         if (comp_mask & IB_PIR_COMPMASK_HOQLIFE) {
329                 if ((p_comp_pi->vl_stall_life & 0x1F) !=
330                     (p_pi->vl_stall_life & 0x1F))
331                         goto Exit;
332         }
333         if (comp_mask & IB_PIR_COMPMASK_OPVLS) {
334                 if ((p_comp_pi->vl_enforce & 0xF0) != (p_pi->vl_enforce & 0xF0))
335                         goto Exit;
336         }
337         if (comp_mask & IB_PIR_COMPMASK_PARENFIN) {
338                 if ((p_comp_pi->vl_enforce & 0x08) != (p_pi->vl_enforce & 0x08))
339                         goto Exit;
340         }
341         if (comp_mask & IB_PIR_COMPMASK_PARENFOUT) {
342                 if ((p_comp_pi->vl_enforce & 0x04) != (p_pi->vl_enforce & 0x04))
343                         goto Exit;
344         }
345         if (comp_mask & IB_PIR_COMPMASK_FILTERRAWIN) {
346                 if ((p_comp_pi->vl_enforce & 0x02) != (p_pi->vl_enforce & 0x02))
347                         goto Exit;
348         }
349         if (comp_mask & IB_PIR_COMPMASK_FILTERRAWOUT) {
350                 if ((p_comp_pi->vl_enforce & 0x01) != (p_pi->vl_enforce & 0x01))
351                         goto Exit;
352         }
353         if (comp_mask & IB_PIR_COMPMASK_MKEYVIO) {
354                 if (p_comp_pi->m_key_violations != p_pi->m_key_violations)
355                         goto Exit;
356         }
357         if (comp_mask & IB_PIR_COMPMASK_PKEYVIO) {
358                 if (p_comp_pi->p_key_violations != p_pi->p_key_violations)
359                         goto Exit;
360         }
361         if (comp_mask & IB_PIR_COMPMASK_QKEYVIO) {
362                 if (p_comp_pi->q_key_violations != p_pi->q_key_violations)
363                         goto Exit;
364         }
365         if (comp_mask & IB_PIR_COMPMASK_GUIDCAP) {
366                 if (p_comp_pi->guid_cap != p_pi->guid_cap)
367                         goto Exit;
368         }
369         if (comp_mask & IB_PIR_COMPMASK_SUBNTO) {
370                 if (ib_port_info_get_timeout(p_comp_pi) !=
371                     ib_port_info_get_timeout(p_pi))
372                         goto Exit;
373         }
374         if (comp_mask & IB_PIR_COMPMASK_RESPTIME) {
375                 if ((p_comp_pi->resp_time_value & 0x1F) !=
376                     (p_pi->resp_time_value & 0x1F))
377                         goto Exit;
378         }
379         if (comp_mask & IB_PIR_COMPMASK_LOCALPHYERR) {
380                 if (ib_port_info_get_local_phy_err_thd(p_comp_pi) !=
381                     ib_port_info_get_local_phy_err_thd(p_pi))
382                         goto Exit;
383         }
384         if (comp_mask & IB_PIR_COMPMASK_OVERRUNERR) {
385                 if (ib_port_info_get_overrun_err_thd(p_comp_pi) !=
386                     ib_port_info_get_overrun_err_thd(p_pi))
387                         goto Exit;
388         }
389
390         __osm_sa_pir_create(sa, p_physp, p_ctxt);
391
392 Exit:
393         OSM_LOG_EXIT(sa->p_log);
394 }
395
396 /**********************************************************************
397  **********************************************************************/
398 static void
399 __osm_sa_pir_by_comp_mask(IN osm_sa_t * sa,
400                           IN osm_node_t * const p_node,
401                           osm_pir_search_ctxt_t * const p_ctxt)
402 {
403         const ib_portinfo_record_t *p_rcvd_rec;
404         ib_net64_t comp_mask;
405         const osm_physp_t *p_physp;
406         uint8_t port_num;
407         uint8_t num_ports;
408         const osm_physp_t *p_req_physp;
409
410         OSM_LOG_ENTER(sa->p_log);
411
412         p_rcvd_rec = p_ctxt->p_rcvd_rec;
413         comp_mask = p_ctxt->comp_mask;
414         p_req_physp = p_ctxt->p_req_physp;
415
416         num_ports = osm_node_get_num_physp(p_node);
417
418         if (comp_mask & IB_PIR_COMPMASK_PORTNUM) {
419                 if (p_rcvd_rec->port_num < num_ports) {
420                         p_physp =
421                             osm_node_get_physp_ptr(p_node,
422                                                    p_rcvd_rec->port_num);
423                         /* Check that the p_physp is valid, and that the
424                            p_physp and the p_req_physp share a pkey. */
425                         if (p_physp &&
426                             osm_physp_share_pkey(sa->p_log, p_req_physp,
427                                                  p_physp))
428                                 __osm_sa_pir_check_physp(sa, p_physp,
429                                                          p_ctxt);
430                 }
431         } else {
432                 for (port_num = 0; port_num < num_ports; port_num++) {
433                         p_physp =
434                             osm_node_get_physp_ptr(p_node, port_num);
435                         if (!p_physp)
436                                 continue;
437
438                         /* if the requester and the p_physp don't share a pkey -
439                            continue */
440                         if (!osm_physp_share_pkey
441                             (sa->p_log, p_req_physp, p_physp))
442                                 continue;
443
444                         __osm_sa_pir_check_physp(sa, p_physp, p_ctxt);
445                 }
446         }
447
448         OSM_LOG_EXIT(sa->p_log);
449 }
450
451 /**********************************************************************
452  **********************************************************************/
453 static void
454 __osm_sa_pir_by_comp_mask_cb(IN cl_map_item_t * const p_map_item,
455                              IN void *context)
456 {
457         osm_node_t *const p_node = (osm_node_t *) p_map_item;
458         osm_pir_search_ctxt_t *const p_ctxt = (osm_pir_search_ctxt_t *) context;
459
460         __osm_sa_pir_by_comp_mask(p_ctxt->sa, p_node, p_ctxt);
461 }
462
463 /**********************************************************************
464  **********************************************************************/
465 void osm_pir_rcv_process(IN void *ctx, IN void *data)
466 {
467         osm_sa_t *sa = ctx;
468         osm_madw_t *p_madw = data;
469         const ib_sa_mad_t *p_rcvd_mad;
470         const ib_portinfo_record_t *p_rcvd_rec;
471         const cl_ptr_vector_t *p_tbl;
472         const osm_port_t *p_port = NULL;
473         const ib_port_info_t *p_pi;
474         cl_qlist_t rec_list;
475         osm_pir_search_ctxt_t context;
476         ib_api_status_t status = IB_SUCCESS;
477         ib_net64_t comp_mask;
478         osm_physp_t *p_req_physp;
479
480         CL_ASSERT(sa);
481
482         OSM_LOG_ENTER(sa->p_log);
483
484         CL_ASSERT(p_madw);
485
486         p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw);
487         p_rcvd_rec =
488             (ib_portinfo_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad);
489         comp_mask = p_rcvd_mad->comp_mask;
490
491         CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_PORTINFO_RECORD);
492
493         /* we only support SubnAdmGet and SubnAdmGetTable methods */
494         if (p_rcvd_mad->method != IB_MAD_METHOD_GET &&
495             p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) {
496                 OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2105: "
497                         "Unsupported Method (%s)\n",
498                         ib_get_sa_method_str(p_rcvd_mad->method));
499                 osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR);
500                 goto Exit;
501         }
502
503         /* update the requester physical port. */
504         p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
505                                                 osm_madw_get_mad_addr_ptr
506                                                 (p_madw));
507         if (p_req_physp == NULL) {
508                 OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2104: "
509                         "Cannot find requester physical port\n");
510                 goto Exit;
511         }
512
513         if (osm_log_is_active(sa->p_log, OSM_LOG_DEBUG))
514                 osm_dump_portinfo_record(sa->p_log, p_rcvd_rec, OSM_LOG_DEBUG);
515
516         p_tbl = &sa->p_subn->port_lid_tbl;
517         p_pi = &p_rcvd_rec->port_info;
518
519         cl_qlist_init(&rec_list);
520
521         context.p_rcvd_rec = p_rcvd_rec;
522         context.p_list = &rec_list;
523         context.comp_mask = p_rcvd_mad->comp_mask;
524         context.sa = sa;
525         context.p_req_physp = p_req_physp;
526         context.is_enhanced_comp_mask =
527             cl_ntoh32(p_rcvd_mad->attr_mod) & (1 << 31);
528
529         cl_plock_acquire(sa->p_lock);
530
531         CL_ASSERT(cl_ptr_vector_get_size(p_tbl) < 0x10000);
532
533         /*
534            If the user specified a LID, it obviously narrows our
535            work load, since we don't have to search every port
536          */
537         if (comp_mask & IB_PIR_COMPMASK_LID) {
538                 status =
539                     osm_get_port_by_base_lid(sa->p_subn, p_rcvd_rec->lid,
540                                              &p_port);
541                 if ((status != IB_SUCCESS) || (p_port == NULL)) {
542                         status = IB_NOT_FOUND;
543                         OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2109: "
544                                 "No port found with LID %u\n",
545                                 cl_ntoh16(p_rcvd_rec->lid));
546                 }
547         } else if (comp_mask & IB_PIR_COMPMASK_BASELID) {
548                 if ((uint16_t) cl_ptr_vector_get_size(p_tbl) >
549                     cl_ntoh16(p_pi->base_lid))
550                         p_port = cl_ptr_vector_get(p_tbl,
551                                                    cl_ntoh16(p_pi->base_lid));
552                 else {
553                         status = IB_NOT_FOUND;
554                         OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2103: "
555                                 "Given LID (%u) is out of range:%u\n",
556                                 cl_ntoh16(p_pi->base_lid),
557                                 cl_ptr_vector_get_size(p_tbl));
558                 }
559         }
560
561         if (status == IB_SUCCESS) {
562                 if (p_port)
563                         __osm_sa_pir_by_comp_mask(sa, p_port->p_node,
564                                                   &context);
565                 else
566                         cl_qmap_apply_func(&sa->p_subn->node_guid_tbl,
567                                            __osm_sa_pir_by_comp_mask_cb,
568                                            &context);
569         }
570
571         cl_plock_release(sa->p_lock);
572
573         /*
574            p922 - The M_Key returned shall be zero, except in the case of a
575            trusted request.
576            Note: In the mad controller we check that the SM_Key received on
577            the mad is valid. Meaning - is either zero or equal to the local
578            sm_key.
579          */
580         if (!p_rcvd_mad->sm_key) {
581                 osm_pir_item_t *item;
582                 for (item = (osm_pir_item_t *) cl_qlist_head(&rec_list);
583                      item != (osm_pir_item_t *) cl_qlist_end(&rec_list);
584                      item = (osm_pir_item_t *)cl_qlist_next(&item->list_item))
585                         item->rec.port_info.m_key = 0;
586         }
587
588         osm_sa_respond(sa, p_madw, sizeof(ib_portinfo_record_t), &rec_list);
589
590 Exit:
591         OSM_LOG_EXIT(sa->p_log);
592 }