+u32 *ping_iter_first(struct lnet_ping_iter *pi,
+ struct lnet_ping_buffer *pbuf,
+ struct lnet_nid *nid)
+{
+ pi->pinfo = &pbuf->pb_info;
+ pi->pos = &pbuf->pb_info.pi_ni;
+ pi->end = (void *)pi->pinfo +
+ min_t(int, pbuf->pb_nbytes,
+ lnet_ping_info_size(pi->pinfo));
+ /* lnet_ping_info_validiate ensures there will be one
+ * lnet_ni_status at the start
+ */
+ if (nid)
+ lnet_nid4_to_nid(pbuf->pb_info.pi_ni[0].ns_nid, nid);
+ return &pbuf->pb_info.pi_ni[0].ns_status;
+}
+
+u32 *ping_iter_next(struct lnet_ping_iter *pi, struct lnet_nid *nid)
+{
+ int off = offsetof(struct lnet_ping_info, pi_ni[pi->pinfo->pi_nnis]);
+
+ if (pi->pos < ((void *)pi->pinfo + off)) {
+ struct lnet_ni_status *ns = pi->pos;
+
+ pi->pos = ns + 1;
+ if (pi->pos > pi->end)
+ return NULL;
+ if (nid)
+ lnet_nid4_to_nid(ns->ns_nid, nid);
+ return &ns->ns_status;
+ }
+
+ while (pi->pinfo->pi_features & LNET_PING_FEAT_LARGE_ADDR) {
+ struct lnet_ni_large_status *lns = pi->pos;
+
+ if (pi->pos + 8 > pi->end)
+ /* Not safe to examine next */
+ return NULL;
+ pi->pos = lnet_ping_sts_next(lns);
+ if (pi->pos > pi->end)
+ return NULL;
+ if (NID_BYTES(&lns->ns_nid) > sizeof(struct lnet_nid))
+ continue;
+ if (nid)
+ *nid = lns->ns_nid;
+ return &lns->ns_status;
+ }
+ return NULL;
+}
+