config: tegra3: enable /dev mount with ACL
[linux-2.6.git] / drivers / firmware / dmi-id.c
index 59c3b5a..94a58a0 100644 (file)
 #include <linux/init.h>
 #include <linux/dmi.h>
 #include <linux/device.h>
-#include <linux/autoconf.h>
-
-#define DEFINE_DMI_ATTR(_name, _mode, _show)           \
-static struct device_attribute sys_dmi_##_name##_attr =        \
-       __ATTR(_name, _mode, _show, NULL);
-
-#define DEFINE_DMI_ATTR_WITH_SHOW(_name, _mode, _field)                        \
-static ssize_t sys_dmi_##_name##_show(struct device *dev,              \
-                                     struct device_attribute *attr,    \
-                                     char *page)                       \
-{                                                                      \
-       ssize_t len;                                                    \
-       len = scnprintf(page, PAGE_SIZE, "%s\n", dmi_get_system_info(_field)); \
-       page[len-1] = '\n';                                             \
-       return len;                                                     \
-}                                                                      \
-DEFINE_DMI_ATTR(_name, _mode, sys_dmi_##_name##_show);
+#include <linux/slab.h>
+
+struct dmi_device_attribute{
+       struct device_attribute dev_attr;
+       int field;
+};
+#define to_dmi_dev_attr(_dev_attr) \
+       container_of(_dev_attr, struct dmi_device_attribute, dev_attr)
+
+static ssize_t sys_dmi_field_show(struct device *dev,
+                                 struct device_attribute *attr,
+                                 char *page)
+{
+       int field = to_dmi_dev_attr(attr)->field;
+       ssize_t len;
+       len = scnprintf(page, PAGE_SIZE, "%s\n", dmi_get_system_info(field));
+       page[len-1] = '\n';
+       return len;
+}
+
+#define DMI_ATTR(_name, _mode, _show, _field)                  \
+       { .dev_attr = __ATTR(_name, _mode, _show, NULL),        \
+         .field = _field }
+
+#define DEFINE_DMI_ATTR_WITH_SHOW(_name, _mode, _field)                \
+static struct dmi_device_attribute sys_dmi_##_name##_attr =    \
+       DMI_ATTR(_name, _mode, sys_dmi_field_show, _field);
 
 DEFINE_DMI_ATTR_WITH_SHOW(bios_vendor,         0444, DMI_BIOS_VENDOR);
 DEFINE_DMI_ATTR_WITH_SHOW(bios_version,                0444, DMI_BIOS_VERSION);
@@ -121,7 +131,8 @@ static ssize_t sys_dmi_modalias_show(struct device *dev,
        return r+1;
 }
 
-DEFINE_DMI_ATTR(modalias, 0444, sys_dmi_modalias_show);
+static struct device_attribute sys_dmi_modalias_attr =
+       __ATTR(modalias, 0444, sys_dmi_modalias_show, NULL);
 
 static struct attribute *sys_dmi_attributes[DMI_STRING_MAX+2];
 
@@ -129,19 +140,22 @@ static struct attribute_group sys_dmi_attribute_group = {
        .attrs = sys_dmi_attributes,
 };
 
-static struct attribute_group* sys_dmi_attribute_groups[] = {
+static const struct attribute_group* sys_dmi_attribute_groups[] = {
        &sys_dmi_attribute_group,
        NULL
 };
 
-static int dmi_dev_uevent(struct device *dev, char **envp,
-                           int num_envp, char *buffer, int buffer_size)
+static int dmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
-       strcpy(buffer, "MODALIAS=");
-       get_modalias(buffer+9, buffer_size-9);
-       envp[0] = buffer;
-       envp[1] = NULL;
-
+       ssize_t len;
+
+       if (add_uevent_var(env, "MODALIAS="))
+               return -ENOMEM;
+       len = get_modalias(&env->buf[env->buflen - 1],
+                          sizeof(env->buf) - env->buflen);
+       if (len >= (sizeof(env->buf) - env->buflen))
+               return -ENOMEM;
+       env->buflen += len;
        return 0;
 }
 
@@ -157,16 +171,13 @@ static struct device *dmi_dev;
 
 #define ADD_DMI_ATTR(_name, _field) \
        if (dmi_get_system_info(_field)) \
-               sys_dmi_attributes[i++] = & sys_dmi_##_name##_attr.attr;
-
-extern int dmi_available;
+               sys_dmi_attributes[i++] = &sys_dmi_##_name##_attr.dev_attr.attr;
 
-static int __init dmi_id_init(void)
+/* In a separate function to keep gcc 3.2 happy - do NOT merge this in
+   dmi_id_init! */
+static void __init dmi_id_init_attr_table(void)
 {
-       int ret, i;
-
-       if (!dmi_available)
-               return -ENODEV;
+       int i;
 
        /* Not necessarily all DMI fields are available on all
         * systems, hence let's built an attribute table of just
@@ -191,6 +202,16 @@ static int __init dmi_id_init(void)
        ADD_DMI_ATTR(chassis_serial,    DMI_CHASSIS_SERIAL);
        ADD_DMI_ATTR(chassis_asset_tag, DMI_CHASSIS_ASSET_TAG);
        sys_dmi_attributes[i++] = &sys_dmi_modalias_attr.attr;
+}
+
+static int __init dmi_id_init(void)
+{
+       int ret;
+
+       if (!dmi_available)
+               return -ENODEV;
+
+       dmi_id_init_attr_table();
 
        ret = class_register(&dmi_class);
        if (ret)
@@ -203,15 +224,17 @@ static int __init dmi_id_init(void)
        }
 
        dmi_dev->class = &dmi_class;
-       strcpy(dmi_dev->bus_id, "id");
+       dev_set_name(dmi_dev, "id");
        dmi_dev->groups = sys_dmi_attribute_groups;
 
        ret = device_register(dmi_dev);
        if (ret)
-               goto fail_class_unregister;
+               goto fail_free_dmi_dev;
 
        return 0;
 
+fail_free_dmi_dev:
+       kfree(dmi_dev);
 fail_class_unregister:
 
        class_unregister(&dmi_class);