root/drivers/platform/x86/wmi-bmof.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. read_bmof
  2. wmi_bmof_probe
  3. wmi_bmof_remove

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * WMI embedded Binary MOF driver
   4  *
   5  * Copyright (c) 2015 Andrew Lutomirski
   6  * Copyright (C) 2017 VMware, Inc. All Rights Reserved.
   7  */
   8 
   9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  10 
  11 #include <linux/acpi.h>
  12 #include <linux/device.h>
  13 #include <linux/fs.h>
  14 #include <linux/kernel.h>
  15 #include <linux/module.h>
  16 #include <linux/string.h>
  17 #include <linux/sysfs.h>
  18 #include <linux/types.h>
  19 #include <linux/wmi.h>
  20 
  21 #define WMI_BMOF_GUID "05901221-D566-11D1-B2F0-00A0C9062910"
  22 
  23 struct bmof_priv {
  24         union acpi_object *bmofdata;
  25         struct bin_attribute bmof_bin_attr;
  26 };
  27 
  28 static ssize_t
  29 read_bmof(struct file *filp, struct kobject *kobj,
  30          struct bin_attribute *attr,
  31          char *buf, loff_t off, size_t count)
  32 {
  33         struct bmof_priv *priv =
  34                 container_of(attr, struct bmof_priv, bmof_bin_attr);
  35 
  36         if (off < 0)
  37                 return -EINVAL;
  38 
  39         if (off >= priv->bmofdata->buffer.length)
  40                 return 0;
  41 
  42         if (count > priv->bmofdata->buffer.length - off)
  43                 count = priv->bmofdata->buffer.length - off;
  44 
  45         memcpy(buf, priv->bmofdata->buffer.pointer + off, count);
  46         return count;
  47 }
  48 
  49 static int wmi_bmof_probe(struct wmi_device *wdev, const void *context)
  50 {
  51         struct bmof_priv *priv;
  52         int ret;
  53 
  54         priv = devm_kzalloc(&wdev->dev, sizeof(struct bmof_priv), GFP_KERNEL);
  55         if (!priv)
  56                 return -ENOMEM;
  57 
  58         dev_set_drvdata(&wdev->dev, priv);
  59 
  60         priv->bmofdata = wmidev_block_query(wdev, 0);
  61         if (!priv->bmofdata) {
  62                 dev_err(&wdev->dev, "failed to read Binary MOF\n");
  63                 return -EIO;
  64         }
  65 
  66         if (priv->bmofdata->type != ACPI_TYPE_BUFFER) {
  67                 dev_err(&wdev->dev, "Binary MOF is not a buffer\n");
  68                 ret = -EIO;
  69                 goto err_free;
  70         }
  71 
  72         sysfs_bin_attr_init(&priv->bmof_bin_attr);
  73         priv->bmof_bin_attr.attr.name = "bmof";
  74         priv->bmof_bin_attr.attr.mode = 0400;
  75         priv->bmof_bin_attr.read = read_bmof;
  76         priv->bmof_bin_attr.size = priv->bmofdata->buffer.length;
  77 
  78         ret = sysfs_create_bin_file(&wdev->dev.kobj, &priv->bmof_bin_attr);
  79         if (ret)
  80                 goto err_free;
  81 
  82         return 0;
  83 
  84  err_free:
  85         kfree(priv->bmofdata);
  86         return ret;
  87 }
  88 
  89 static int wmi_bmof_remove(struct wmi_device *wdev)
  90 {
  91         struct bmof_priv *priv = dev_get_drvdata(&wdev->dev);
  92 
  93         sysfs_remove_bin_file(&wdev->dev.kobj, &priv->bmof_bin_attr);
  94         kfree(priv->bmofdata);
  95         return 0;
  96 }
  97 
  98 static const struct wmi_device_id wmi_bmof_id_table[] = {
  99         { .guid_string = WMI_BMOF_GUID },
 100         { },
 101 };
 102 
 103 static struct wmi_driver wmi_bmof_driver = {
 104         .driver = {
 105                 .name = "wmi-bmof",
 106         },
 107         .probe = wmi_bmof_probe,
 108         .remove = wmi_bmof_remove,
 109         .id_table = wmi_bmof_id_table,
 110 };
 111 
 112 module_wmi_driver(wmi_bmof_driver);
 113 
 114 MODULE_DEVICE_TABLE(wmi, wmi_bmof_id_table);
 115 MODULE_AUTHOR("Andrew Lutomirski <luto@kernel.org>");
 116 MODULE_DESCRIPTION("WMI embedded Binary MOF driver");
 117 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */