Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3c7c8468 authored by Tomas Winkler's avatar Tomas Winkler Committed by Greg Kroah-Hartman
Browse files

mei: add async event notification ioctls



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: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent b38a362f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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!
+44 −1
Original line number Diff line number Diff line
@@ -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
=====================
+67 −0
Original line number Diff line number Diff line
@@ -445,6 +445,45 @@ static int mei_ioctl_connect_client(struct file *file,
	return rets;
}

/**
 * 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
 *
@@ -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;
+19 −0
Original line number Diff line number Diff line
@@ -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  */