diff mbox series

[RFC,v2,12/20] dm: add tag support

Message ID 20211210064947.73361-13-takahiro.akashi@linaro.org
State New
Headers show
Series efi_loader: more tightly integrate UEFI disks to driver model | expand

Commit Message

AKASHI Takahiro Dec. 10, 2021, 6:49 a.m. UTC
With dm-tag feature, any U-Boot subsystem is allowed to associate
arbitrary number of data with a particular udevice. This can been
see as expanding "struct udevice" without modifying the definition.

As a first user, UEFI subsystem makes use of tags to associate
an efi_disk object with a block device.

Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
---
 drivers/core/Makefile |   2 +-
 drivers/core/tag.c    | 162 ++++++++++++++++++++++++++++++++++++++++++
 include/dm/tag.h      |  76 ++++++++++++++++++++
 3 files changed, 239 insertions(+), 1 deletion(-)
 create mode 100644 drivers/core/tag.c
 create mode 100644 include/dm/tag.h

Comments

Simon Glass Dec. 13, 2021, 12:51 p.m. UTC | #1
Hi Takahiro,

On Thu, 9 Dec 2021 at 23:58, AKASHI Takahiro <takahiro.akashi@linaro.org> wrote:
>
> With dm-tag feature, any U-Boot subsystem is allowed to associate
> arbitrary number of data with a particular udevice. This can been
> see as expanding "struct udevice" without modifying the definition.
>
> As a first user, UEFI subsystem makes use of tags to associate
> an efi_disk object with a block device.
>
> Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> ---
>  drivers/core/Makefile |   2 +-
>  drivers/core/tag.c    | 162 ++++++++++++++++++++++++++++++++++++++++++
>  include/dm/tag.h      |  76 ++++++++++++++++++++
>  3 files changed, 239 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/core/tag.c
>  create mode 100644 include/dm/tag.h

Needs comments and a test, but looks good.

How does the list itself get inited?

Regards,
Simon
AKASHI Takahiro Dec. 14, 2021, 7:05 a.m. UTC | #2
On Mon, Dec 13, 2021 at 05:51:45AM -0700, Simon Glass wrote:
> Hi Takahiro,
> 
> On Thu, 9 Dec 2021 at 23:58, AKASHI Takahiro <takahiro.akashi@linaro.org> wrote:
> >
> > With dm-tag feature, any U-Boot subsystem is allowed to associate
> > arbitrary number of data with a particular udevice. This can been
> > see as expanding "struct udevice" without modifying the definition.
> >
> > As a first user, UEFI subsystem makes use of tags to associate
> > an efi_disk object with a block device.
> >
> > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > ---
> >  drivers/core/Makefile |   2 +-
> >  drivers/core/tag.c    | 162 ++++++++++++++++++++++++++++++++++++++++++
> >  include/dm/tag.h      |  76 ++++++++++++++++++++
> >  3 files changed, 239 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/core/tag.c
> >  create mode 100644 include/dm/tag.h
> 
> Needs comments and a test, but looks good.
> 
> How does the list itself get inited?

Isn't LIST_HEAD(dmtag_list) enough?

-Takahiro Akashi


> Regards,
> Simon
Simon Glass Dec. 28, 2021, 8:32 a.m. UTC | #3
Hi Takahiro,

On Tue, 14 Dec 2021 at 00:05, AKASHI Takahiro
<takahiro.akashi@linaro.org> wrote:
>
> On Mon, Dec 13, 2021 at 05:51:45AM -0700, Simon Glass wrote:
> > Hi Takahiro,
> >
> > On Thu, 9 Dec 2021 at 23:58, AKASHI Takahiro <takahiro.akashi@linaro.org> wrote:
> > >
> > > With dm-tag feature, any U-Boot subsystem is allowed to associate
> > > arbitrary number of data with a particular udevice. This can been
> > > see as expanding "struct udevice" without modifying the definition.
> > >
> > > As a first user, UEFI subsystem makes use of tags to associate
> > > an efi_disk object with a block device.
> > >
> > > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > ---
> > >  drivers/core/Makefile |   2 +-
> > >  drivers/core/tag.c    | 162 ++++++++++++++++++++++++++++++++++++++++++
> > >  include/dm/tag.h      |  76 ++++++++++++++++++++
> > >  3 files changed, 239 insertions(+), 1 deletion(-)
> > >  create mode 100644 drivers/core/tag.c
> > >  create mode 100644 include/dm/tag.h
> >
> > Needs comments and a test, but looks good.
> >
> > How does the list itself get inited?
>
> Isn't LIST_HEAD(dmtag_list) enough?

Yes but that is a BSS var so cannot be used in SPL or before
relocation. How about moving it to global_data?

Regards,
Simon
diff mbox series

Patch

diff --git a/drivers/core/Makefile b/drivers/core/Makefile
index 5edd4e413576..3742e7574525 100644
--- a/drivers/core/Makefile
+++ b/drivers/core/Makefile
@@ -2,7 +2,7 @@ 
 #
 # Copyright (c) 2013 Google, Inc
 
-obj-y	+= device.o fdtaddr.o lists.o root.o uclass.o util.o
+obj-y	+= device.o fdtaddr.o lists.o root.o uclass.o util.o tag.o
 obj-$(CONFIG_$(SPL_TPL_)ACPIGEN) += acpi.o
 obj-$(CONFIG_DEVRES) += devres.o
 obj-$(CONFIG_$(SPL_)DM_DEVICE_REMOVE)	+= device-remove.o
diff --git a/drivers/core/tag.c b/drivers/core/tag.c
new file mode 100644
index 000000000000..562df3590c44
--- /dev/null
+++ b/drivers/core/tag.c
@@ -0,0 +1,162 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2021 Linaro Limited
+ *			Author: AKASHI Takahiro
+ */
+
+#include <malloc.h>
+#include <dm/tag.h>
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/types.h>
+
+struct udevice;
+
+static LIST_HEAD(dmtag_list);
+
+/**
+ * dev_tag_set_ptr()
+ *
+ */
+int dev_tag_set_ptr(struct udevice *dev, enum dm_tag_t tag, void *ptr)
+{
+	struct dmtag_node *node;
+
+	if (!dev || tag > DM_TAG_COUNT)
+		return -EINVAL;
+
+	list_for_each_entry(node, &dmtag_list, sibling) {
+		if (node->dev == dev && node->tag == tag)
+			return -EEXIST;
+	}
+
+	node = calloc(sizeof(*node), 1);
+	if (!node)
+		return -ENOSPC;
+
+	node->dev = dev;
+	node->tag = tag;
+	node->ptr = ptr;
+	list_add_tail(&node->sibling, &dmtag_list);
+
+	return 0;
+}
+
+/**
+ * dev_tag_set_val()
+ *
+ */
+int dev_tag_set_val(struct udevice *dev, enum dm_tag_t tag, ulong val)
+{
+	struct dmtag_node *node;
+
+	if (!dev || tag > DM_TAG_COUNT)
+		return -EINVAL;
+
+	list_for_each_entry(node, &dmtag_list, sibling) {
+		if (node->dev == dev && node->tag == tag)
+			return -EEXIST;
+	}
+
+	node = calloc(sizeof(*node), 1);
+	if (!node)
+		return -ENOSPC;
+
+	node->dev = dev;
+	node->tag = tag;
+	node->val = val;
+	list_add_tail(&node->sibling, &dmtag_list);
+
+	return 0;
+}
+
+/**
+ * dev_tag_get_ptr()
+ *
+ */
+int dev_tag_get_ptr(struct udevice *dev, enum dm_tag_t tag, void **ptrp)
+{
+	struct dmtag_node *node;
+
+	if (!dev || tag > DM_TAG_COUNT)
+		return -EINVAL;
+
+	list_for_each_entry(node, &dmtag_list, sibling) {
+		if (node->dev == dev && node->tag == tag) {
+			*ptrp = node->ptr;
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+/**
+ * dev_tag_get_val()
+ *
+ */
+int dev_tag_get_val(struct udevice *dev, enum dm_tag_t tag, ulong *valp)
+{
+	struct dmtag_node *node;
+
+	if (!dev || tag > DM_TAG_COUNT)
+		return -EINVAL;
+
+	list_for_each_entry(node, &dmtag_list, sibling) {
+		if (node->dev == dev && node->tag == tag) {
+			*valp = node->val;
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+/**
+ * dev_tag_del()
+ *
+ */
+int dev_tag_del(struct udevice *dev, enum dm_tag_t tag)
+{
+	struct dmtag_node *node, *tmp;
+
+	if (!dev || tag > DM_TAG_COUNT)
+		return -EINVAL;
+
+	list_for_each_entry_safe(node, tmp, &dmtag_list, sibling) {
+		if (node->dev == dev && node->tag == tag) {
+			list_del(&node->sibling);
+			free(node);
+
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+/**
+ * dev_tag_del_all()
+ *
+ */
+int dev_tag_del_all(struct udevice *dev)
+{
+	struct dmtag_node *node, *tmp;
+	bool found = false;
+
+	if (!dev)
+		return -EINVAL;
+
+	list_for_each_entry_safe(node, tmp, &dmtag_list, sibling) {
+		if (node->dev == dev) {
+			list_del(&node->sibling);
+			free(node);
+			found = true;
+		}
+	}
+
+	if (found)
+		return 0;
+
+	return -ENOENT;
+}
diff --git a/include/dm/tag.h b/include/dm/tag.h
new file mode 100644
index 000000000000..8f81b4f7ffaa
--- /dev/null
+++ b/include/dm/tag.h
@@ -0,0 +1,76 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) 2021 Linaro Limited
+ *			Author: AKASHI Takahiro
+ */
+
+#ifndef _DM_TAG_H
+#define _DM_TAG_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+
+struct udevice;
+
+enum dm_tag_t {
+	DM_TAG_EFI = 0,
+
+	DM_TAG_COUNT,
+};
+
+/**
+ * dmtag_node
+ *
+ * @sibling: List of dm-tag nodes
+ * @dev:     Associated udevice
+ * @tag:     Tag type
+ * @ptr:     Pointer as a value
+ * @val:     Value
+ */
+struct dmtag_node {
+	struct list_head sibling;
+	struct  udevice *dev;
+	enum dm_tag_t tag;
+	union {
+		void *ptr;
+		ulong val;
+	};
+};
+
+/**
+ * dev_tag_set_ptr()
+ *
+ */
+int dev_tag_set_ptr(struct udevice *dev, enum dm_tag_t tag, void *ptr);
+
+/**
+ * dev_tag_set_val()
+ *
+ */
+int dev_tag_set_val(struct udevice *dev, enum dm_tag_t tag, ulong val);
+
+/**
+ * dev_tag_get_ptr()
+ *
+ */
+int dev_tag_get_ptr(struct udevice *dev, enum dm_tag_t tag, void **ptrp);
+
+/**
+ * dev_tag_get_val()
+ *
+ */
+int dev_tag_get_val(struct udevice *dev, enum dm_tag_t tag, ulong *valp);
+
+/**
+ * dev_tag_del()
+ *
+ */
+int dev_tag_del(struct udevice *dev, enum dm_tag_t tag);
+
+/**
+ * dev_tag_del_all()
+ *
+ */
+int dev_tag_del_all(struct udevice *dev);
+
+#endif /* _DM_TAG_H */