lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <f17812d70902031952x2fecef8bsb30e84ce6685f572@mail.gmail.com>
Date:	Wed, 4 Feb 2009 11:52:40 +0800
From:	Eric Miao <eric.y.miao@...il.com>
To:	Greg KH <greg@...ah.com>
Cc:	Ben Dooks <ben-linux@...ff.org>,
	LKML <linux-kernel@...r.kernel.org>,
	Kay Sievers <kay.sievers@...y.org>
Subject: Re: [PATCH 2/2 RESEND] platform: introduce module id table for 
	platform devices

On Wed, Feb 4, 2009 at 9:16 AM, Greg KH <greg@...ah.com> wrote:
> On Mon, Feb 02, 2009 at 06:11:48PM +0800, Eric Miao wrote:
>> >
>> > surely you mean PLATFORM_NAME_SIZE in this struct?
>>
>> Indeed, patch updated below (and as attached):
>
> With this patch, I get the following warning:
>        drivers/base/platform.c:598: warning: assignment discards qualifiers from pointer target type
>
> Also, don't put platform_match_id() underneath the comments for
> platform_match(), that will only confuse the kernel-doc scripts and any
> developer looking at the code.
>
> Care to fix it up and resend?
>

OK, updated patch below:

>From 2dfe47b26ba0bf72974ae4ca2bb86b211a78596b Mon Sep 17 00:00:00 2001
From: Eric Miao <eric.miao@...vell.com>
Date: Tue, 30 Dec 2008 14:20:59 +0800
Subject: [PATCH] platform: introduce module id table for platform devices

Now platform_device is being widely used on SoC processors where the
peripherals are attached to the system bus, which is simple enough.

However, silicon IPs for these SoCs are usually shared heavily across
a family of processors, even products from different companies.  This
makes the original simple driver name based matching insufficient, or
simply not straight-forward.

Introduce a module id table for platform devices, and makes it clear
that a platform driver is able to support some shared IP and handle
slight differences across different platforms (by 'driver_data').
Module alias is handled automatically when a MODULE_DEVICE_TABLE()
is defined.

To not disturb the current platform drivers too much, the matched id
entry is recorded and can be retrieved by platform_get_device_id().

Signed-off-by: Eric Miao <eric.miao@...vell.com>
---
 drivers/base/platform.c         |   23 ++++++++++++++++++++++-
 include/linux/mod_devicetable.h |    9 +++++++++
 include/linux/platform_device.h |    6 ++++++
 scripts/mod/file2alias.c        |   12 ++++++++++++
 4 files changed, 49 insertions(+), 1 deletions(-)

diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index d0591f0..ae65607 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -587,10 +587,25 @@ static int platform_uevent(struct device *dev,
struct kobj_uevent_env *env)
 {
 	struct platform_device	*pdev = to_platform_device(dev);

-	add_uevent_var(env, "MODALIAS=platform:%s", pdev->name);
+	add_uevent_var(env, "MODALIAS=%s%s", PLATFORM_MODULE_PREFIX,
+		(pdev->id_entry) ? pdev->id_entry->name : pdev->name);
 	return 0;
 }

+static const struct platform_device_id *platform_match_id(
+			struct platform_device_id *id,
+			struct platform_device *pdev)
+{
+	while (id->name[0]) {
+		if (strcmp(pdev->name, id->name) == 0) {
+			pdev->id_entry = id;
+			return id;
+		}
+		id++;
+	}
+	return NULL;
+}
+
 /**
  * platform_match - bind platform device to platform driver.
  * @dev: device.
@@ -607,7 +622,13 @@ static int platform_uevent(struct device *dev,
struct kobj_uevent_env *env)
 static int platform_match(struct device *dev, struct device_driver *drv)
 {
 	struct platform_device *pdev = to_platform_device(dev);
+	struct platform_driver *pdrv = to_platform_driver(drv);
+
+	/* match against the id table first */
+	if (pdrv->id_table)
+		return platform_match_id(pdrv->id_table, pdev) != NULL;

+	/* fall-back to driver name match */
 	return (strncmp(pdev->name, drv->name, BUS_ID_SIZE) == 0);
 }

diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 97b91d1..05542d3 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -447,4 +447,13 @@ struct dmi_system_id {

 #define DMI_MATCH(a, b)	{ a, b }

+#define PLATFORM_NAME_SIZE	20
+#define PLATFORM_MODULE_PREFIX	"platform:"
+
+struct platform_device_id {
+	char name[PLATFORM_NAME_SIZE];
+	kernel_ulong_t driver_data
+			__attribute__((aligned(sizeof(kernel_ulong_t))));
+};
+
 #endif /* LINUX_MOD_DEVICETABLE_H */
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 4b8cc6a..7edc570 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -12,6 +12,7 @@
 #define _PLATFORM_DEVICE_H_

 #include <linux/device.h>
+#include <linux/mod_devicetable.h>

 struct platform_device {
 	const char	* name;
@@ -19,8 +20,12 @@ struct platform_device {
 	struct device	dev;
 	u32		num_resources;
 	struct resource	* resource;
+
+	struct platform_device_id	*id_entry;
 };

+#define platform_get_device_id(pdev)	((pdev)->id_entry)
+
 #define to_platform_device(x) container_of((x), struct platform_device, dev)

 extern int platform_device_register(struct platform_device *);
@@ -57,6 +62,7 @@ struct platform_driver {
 	int (*resume)(struct platform_device *);
 	struct pm_ext_ops *pm;
 	struct device_driver driver;
+	struct platform_device_id *id_table;
 };

 extern int platform_driver_register(struct platform_driver *);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index d4dc222..f71f5e6 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -696,6 +696,14 @@ static int do_dmi_entry(const char *filename,
struct dmi_system_id *id,
 	strcat(alias, ":");
 	return 1;
 }
+
+static int do_platform_entry(const char *filename,
+			     struct platform_device_id *id, char *alias)
+{
+	sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name);
+	return 1;
+}
+
 /* Ignore any prefix, eg. some architectures prepend _ */
 static inline int sym_is(const char *symbol, const char *name)
 {
@@ -835,6 +843,10 @@ void handle_moddevtable(struct module *mod,
struct elf_info *info,
 		do_table(symval, sym->st_size,
 			 sizeof(struct dmi_system_id), "dmi",
 			 do_dmi_entry, mod);
+	else if (sym_is(symname, "__mod_platform_device_table"))
+		do_table(symval, sym->st_size,
+			 sizeof(struct platform_device_id), "platform",
+			 do_platform_entry, mod);
 	free(zeros);
 }

-- 
1.6.0.4

View attachment "0002-platform-introduce-module-id-table-for-platform-dev.patch" of type "text/x-diff" (5228 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ