Add ioctl IOCTL_MEI_NOTIFY_SET for enabling and disabling
async event notification.
Add ioctl IOCTL_MEI_NOTIFY_GET for receiving and acking
an event notification.

Signed-off-by: Tomas Winkler <tomas.wink...@intel.com>
Signed-off-by: Alexander Usyskin <alexander.usys...@intel.com>
---
 Documentation/ioctl/ioctl-number.txt   |  2 +
 Documentation/misc-devices/mei/mei.txt | 45 ++++++++++++++++++++++-
 drivers/misc/mei/main.c                | 67 ++++++++++++++++++++++++++++++++++
 include/uapi/linux/mei.h               | 19 ++++++++++
 4 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/Documentation/ioctl/ioctl-number.txt 
b/Documentation/ioctl/ioctl-number.txt
index 611c52267d24..141f847c7648 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -124,6 +124,8 @@ Code  Seq#(hex)     Include File            Comments
 'H'    00-7F   linux/hiddev.h          conflict!
 'H'    00-0F   linux/hidraw.h          conflict!
 'H'    01      linux/mei.h             conflict!
+'H'    02      linux/mei.h             conflict!
+'H'    03      linux/mei.h             conflict!
 'H'    00-0F   sound/asound.h          conflict!
 'H'    20-40   sound/asound_fm.h       conflict!
 'H'    80-8F   sound/sfnt_info.h       conflict!
diff --git a/Documentation/misc-devices/mei/mei.txt 
b/Documentation/misc-devices/mei/mei.txt
index 8d47501bba0a..91c1fa34f48b 100644
--- a/Documentation/misc-devices/mei/mei.txt
+++ b/Documentation/misc-devices/mei/mei.txt
@@ -96,7 +96,7 @@ A code snippet for an application communicating with Intel 
AMTHI client:
 IOCTL
 =====
 
-The Intel MEI Driver supports the following IOCTL command:
+The Intel MEI Driver supports the following IOCTL commands:
        IOCTL_MEI_CONNECT_CLIENT        Connect to firmware Feature (client).
 
        usage:
@@ -125,6 +125,49 @@ The Intel MEI Driver supports the following IOCTL command:
         data that can be sent or received. (e.g. if MTU=2K, can send
         requests up to bytes 2k and received responses up to 2k bytes).
 
+       IOCTL_MEI_NOTIFY_SET: enable or disable event notifications
+
+       Usage:
+               uint32_t enable;
+               ioctl(fd, IOCTL_MEI_NOTIFY_SET, &enable);
+
+       Inputs:
+               uint32_t enable = 1;
+               or
+               uint32_t enable[disable] = 0;
+
+       Error returns:
+               EINVAL  Wrong IOCTL Number
+               ENODEV  Device  is not initialized or the client not connected
+               ENOMEM  Unable to allocate memory to client internal data.
+               EFAULT  Fatal Error (e.g. Unable to access user input data)
+               EOPNOTSUPP if the device doesn't support the feature
+
+       Notes:
+       The client must be connected in order to enable notification events
+
+
+       IOCTL_MEI_NOTIFY_GET : retrieve event
+
+       Usage:
+               uint32_t event;
+               ioctl(fd, IOCTL_MEI_NOTIFY_GET, &event);
+
+       Outputs:
+               1 - if an event is pending
+               0 - if there is no even pending
+
+       Error returns:
+               EINVAL  Wrong IOCTL Number
+               ENODEV  Device is not initialized or the client not connected
+               ENOMEM  Unable to allocate memory to client internal data.
+               EFAULT  Fatal Error (e.g. Unable to access user input data)
+               EOPNOTSUPP if the device doesn't support the feature
+
+       Notes:
+       The client must be connected and event notification has to be enabled
+       in order to receive an event
+
 
 Intel ME Applications
 =====================
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index e9513d651cd3..ffa70035af29 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -446,6 +446,45 @@ end:
 }
 
 /**
+ * mei_ioctl_client_notify_request -
+ *     propagate event notification request to client
+ *
+ * @file: pointer to file structure
+ * @request: 0 - disable, 1 - enable
+ *
+ * Return: 0 on success , <0 on error
+ */
+static int mei_ioctl_client_notify_request(struct file *file, u32 request)
+{
+       struct mei_cl *cl = file->private_data;
+
+       return mei_cl_notify_request(cl, file, request);
+}
+
+/**
+ * mei_ioctl_client_notify_get -  wait for notification request
+ *
+ * @file: pointer to file structure
+ * @notify_get: 0 - disable, 1 - enable
+ *
+ * Return: 0 on success , <0 on error
+ */
+static int mei_ioctl_client_notify_get(struct file *file, u32 *notify_get)
+{
+       struct mei_cl *cl = file->private_data;
+       bool notify_ev;
+       bool block = (file->f_flags & O_NONBLOCK) == 0;
+       int rets;
+
+       rets = mei_cl_notify_get(cl, block, &notify_ev);
+       if (rets)
+               return rets;
+
+       *notify_get = notify_ev ? 1 : 0;
+       return 0;
+}
+
+/**
  * mei_ioctl - the IOCTL function
  *
  * @file: pointer to file structure
@@ -459,6 +498,7 @@ static long mei_ioctl(struct file *file, unsigned int cmd, 
unsigned long data)
        struct mei_device *dev;
        struct mei_cl *cl = file->private_data;
        struct mei_connect_client_data connect_data;
+       u32 notify_get, notify_req;
        int rets;
 
 
@@ -499,6 +539,33 @@ static long mei_ioctl(struct file *file, unsigned int cmd, 
unsigned long data)
 
                break;
 
+       case IOCTL_MEI_NOTIFY_SET:
+               dev_dbg(dev->dev, ": IOCTL_MEI_NOTIFY_SET.\n");
+               if (copy_from_user(&notify_req,
+                                  (char __user *)data, sizeof(notify_req))) {
+                       dev_dbg(dev->dev, "failed to copy data from 
userland\n");
+                       rets = -EFAULT;
+                       goto out;
+               }
+               rets = mei_ioctl_client_notify_request(file, notify_req);
+               break;
+
+       case IOCTL_MEI_NOTIFY_GET:
+               dev_dbg(dev->dev, ": IOCTL_MEI_NOTIFY_GET.\n");
+               rets = mei_ioctl_client_notify_get(file, &notify_get);
+               if (rets)
+                       goto out;
+
+               dev_dbg(dev->dev, "copy connect data to user\n");
+               if (copy_to_user((char __user *)data,
+                               &notify_get, sizeof(notify_get))) {
+                       dev_dbg(dev->dev, "failed to copy data to userland\n");
+                       rets = -EFAULT;
+                       goto out;
+
+               }
+               break;
+
        default:
                dev_err(dev->dev, ": unsupported ioctl %d.\n", cmd);
                rets = -ENOIOCTLCMD;
diff --git a/include/uapi/linux/mei.h b/include/uapi/linux/mei.h
index bc0d8b69c49e..7c3b64f6a215 100644
--- a/include/uapi/linux/mei.h
+++ b/include/uapi/linux/mei.h
@@ -107,4 +107,23 @@ struct mei_connect_client_data {
        };
 };
 
+/**
+ * DOC: set and unset event notification for a connected client
+ *
+ * The IOCTL argument is 1 for enabling event notification and 0 for
+ * disabling the service
+ * Return:  -EOPNOTSUPP if the devices doesn't support the feature
+ */
+#define IOCTL_MEI_NOTIFY_SET _IOW('H', 0x02, __u32)
+
+/**
+ * DOC: retrieve notification
+ *
+ * The IOCTL output argument is 1 if an event was is pending and 0 otherwise
+ * the ioctl has to be called in order to acknowledge pending event
+ *
+ * Return:  -EOPNOTSUPP if the devices doesn't support the feature
+ */
+#define IOCTL_MEI_NOTIFY_GET _IOR('H', 0x03, __u32)
+
 #endif /* _LINUX_MEI_H  */
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to