aboutsummaryrefslogtreecommitdiff
path: root/external
diff options
context:
space:
mode:
authorOliver O'Halloran <oohall@gmail.com>2017-11-08 19:59:10 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-11-20 20:35:24 -0600
commit07d6b1a134126e9e276feb8f8b818313d3e8b7f9 (patch)
tree2da25f882e5f8cc55a6124d5001aaa52e8e85d7a /external
parent1e038388f385eea2cbc0dae803442dc1fc140372 (diff)
downloadskiboot-07d6b1a134126e9e276feb8f8b818313d3e8b7f9.zip
skiboot-07d6b1a134126e9e276feb8f8b818313d3e8b7f9.tar.gz
skiboot-07d6b1a134126e9e276feb8f8b818313d3e8b7f9.tar.bz2
gard: Add iterators
Add a `for_each_gard` iterator rather than using do_iterate. Callbacks are banned under the Genoa convention and we need to apply a zero-tolerance policy. Signed-off-by: Oliver O'Halloran <oohall@gmail.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'external')
-rw-r--r--external/gard/gard.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/external/gard/gard.c b/external/gard/gard.c
index 0c8ac47..c43b859 100644
--- a/external/gard/gard.c
+++ b/external/gard/gard.c
@@ -212,6 +212,37 @@ static int do_iterate(struct gard_ctx *ctx,
return rc;
}
+/*
+ * read the next guard record into the supplied buffer (gard)
+ *
+ * returns the record id (nb: 1 based not zero)
+ *
+ */
+static int __gard_next(struct gard_ctx *ctx, int pos, struct gard_record *gard, int *rc)
+{
+ uint32_t offset = pos * sizeof_gard(ctx);
+
+ if (offset > ctx->gard_data_len) /* too big */
+ return -1;
+
+ /* you lose error handling information, *gruble* */
+ memset(gard, 0, sizeof(*gard));
+ *rc = blocklevel_read(ctx->bl, ctx->gard_data_pos + offset,
+ gard, sizeof(*gard));
+
+ if (!is_valid_record(gard))
+ return -1;
+
+ if (*rc)
+ return -1;
+
+ return pos;
+}
+
+#define for_each_gard(ctx, pos, gard, rc) \
+ for (pos = __gard_next(ctx, 0, gard, rc); \
+ pos >= 0; pos = __gard_next(ctx, ++pos, gard, rc))
+
static int get_largest_pos_i(struct gard_ctx *ctx, int pos, struct gard_record *gard, void *priv)
{
(void)ctx;