r->fp = stderr;
if (fp)
r->fp = fp;
+ list_head_init(&r->hosts);
+ list_head_init(&r->endpoints);
return r;
}
{
struct nvme_mi_ep *ep;
- ep = malloc(sizeof(*ep));
+ ep = calloc(1, sizeof(*ep));
+ list_node_init(&ep->root_entry);
ep->root = root;
return ep;
{
if (ep->transport->close)
ep->transport->close(ep);
+ list_del(&ep->root_entry);
free(ep);
}
return s;
}
+
+nvme_mi_ep_t nvme_mi_first_endpoint(nvme_root_t m)
+{
+ return list_top(&m->endpoints, struct nvme_mi_ep, root_entry);
+}
+
+nvme_mi_ep_t nvme_mi_next_endpoint(nvme_root_t m, nvme_mi_ep_t ep)
+{
+ return ep ? list_next(&m->endpoints, ep, root_entry) : NULL;
+}
*/
typedef struct nvme_mi_ep * nvme_mi_ep_t;
+/**
+ * nvme_mi_first_endpoint - Start endpoint iterator
+ * @m: &nvme_root_t object
+ *
+ * Return: first MI endpoint object under this root, or NULL if no endpoints
+ * are present.
+ *
+ * See: &nvme_mi_next_endpoint, &nvme_mi_for_each_endpoint
+ */
+nvme_mi_ep_t nvme_mi_first_endpoint(nvme_root_t m);
+
+/**
+ * nvme_mi_next_endpoint - Continue endpoint iterator
+ * @m: &nvme_root_t object
+ * @e: &nvme_mi_ep_t current position of iterator
+ *
+ * Return: next endpoint MI endpoint object after @e under this root, or NULL
+ * if no further endpoints are present.
+ *
+ * See: &nvme_mi_first_endpoint, &nvme_mi_for_each_endpoint
+ */
+nvme_mi_ep_t nvme_mi_next_endpoint(nvme_root_t m, nvme_mi_ep_t e);
+
+/**
+ * nvme_mi_for_each_endpoint - Iterator for NVMe-MI endpoints.
+ * @m: &nvme_root_t containing endpoints
+ * @e: &nvme_mi_ep_t object, set on each iteration
+ */
+#define nvme_mi_for_each_endpoint(m, e) \
+ for (e = nvme_mi_first_endpoint(m); e != NULL; \
+ e = nvme_mi_next_endpoint(m, e))
+
struct nvme_mi_ctrl;
/**