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

Commit 285e2996 authored by Alexander Usyskin's avatar Alexander Usyskin Committed by Greg Kroah-Hartman
Browse files

mei: hbm: revamp client connect and disconnection status



1. Return -ENOTTY on client connect if the requested client was not found
 on the enumeration list or the client was internally disabled, in the later
 case FW will return NOT_FOUND.
2. Return -EBUSY if the client cannot be connected because of resource
 contention
3. Change response status enum to have MEI_CL_ prefix
4. Add function to translate response status to a string
for more readable logging

Signed-off-by: default avatarAlexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 48705693
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -521,18 +521,19 @@ int mei_cl_connect(struct mei_cl *cl, struct file *file)
	}

	mutex_unlock(&dev->device_lock);
	rets = wait_event_timeout(dev->wait_recvd_msg,
	wait_event_timeout(dev->wait_recvd_msg,
			(cl->state == MEI_FILE_CONNECTED ||
			 cl->state == MEI_FILE_DISCONNECTED),
			mei_secs_to_jiffies(MEI_CL_CONNECT_TIMEOUT));
	mutex_lock(&dev->device_lock);

	if (cl->state != MEI_FILE_CONNECTED) {
		rets = -EFAULT;
		/* something went really wrong */
		if (!cl->status)
			cl->status = -EFAULT;

		mei_io_list_flush(&dev->ctrl_rd_list, cl);
		mei_io_list_flush(&dev->ctrl_wr_list, cl);
		goto out;
	}

	rets = cl->status;
+43 −24
Original line number Diff line number Diff line
@@ -23,6 +23,40 @@
#include "hbm.h"
#include "hw-me.h"

static const char *mei_cl_conn_status_str(enum mei_cl_connect_status status)
{
#define MEI_CL_CS(status) case MEI_CL_CONN_##status: return #status
	switch (status) {
	MEI_CL_CS(SUCCESS);
	MEI_CL_CS(NOT_FOUND);
	MEI_CL_CS(ALREADY_STARTED);
	MEI_CL_CS(OUT_OF_RESOURCES);
	MEI_CL_CS(MESSAGE_SMALL);
	default: return "unknown";
	}
#undef MEI_CL_CCS
}

/**
 * mei_cl_conn_status_to_errno - convert client connect response
 * status to error code
 *
 * @status: client connect response status
 *
 * returns corresponding error code
 */
static int mei_cl_conn_status_to_errno(enum mei_cl_connect_status status)
{
	switch (status) {
	case MEI_CL_CONN_SUCCESS:          return 0;
	case MEI_CL_CONN_NOT_FOUND:        return -ENOTTY;
	case MEI_CL_CONN_ALREADY_STARTED:  return -EBUSY;
	case MEI_CL_CONN_OUT_OF_RESOURCES: return -EBUSY;
	case MEI_CL_CONN_MESSAGE_SMALL:    return -EINVAL;
	default:                           return -EINVAL;
	}
}

/**
 * mei_hbm_me_cl_allocate - allocates storage for me clients
 *
@@ -111,14 +145,11 @@ static bool is_treat_specially_client(struct mei_cl *cl,
		struct hbm_client_connect_response *rs)
{
	if (mei_hbm_cl_addr_equal(cl, rs)) {
		if (!rs->status) {
		if (rs->status == MEI_CL_CONN_SUCCESS)
			cl->state = MEI_FILE_CONNECTED;
			cl->status = 0;

		} else {
		else
			cl->state = MEI_FILE_DISCONNECTED;
			cl->status = -ENODEV;
		}
		cl->status = mei_cl_conn_status_to_errno(rs->status);
		cl->timer_count = 0;

		return true;
@@ -438,14 +469,8 @@ static void mei_hbm_cl_disconnect_res(struct mei_device *dev,
	struct mei_cl *cl;
	struct mei_cl_cb *pos = NULL, *next = NULL;

	dev_dbg(&dev->pdev->dev,
			"disconnect_response:\n"
			"ME Client = %d\n"
			"Host Client = %d\n"
			"Status = %d\n",
			rs->me_addr,
			rs->host_addr,
			rs->status);
	dev_dbg(&dev->pdev->dev, "hbm: disconnect response cl:host=%02d me=%02d status=%d\n",
			rs->me_addr, rs->host_addr, rs->status);

	list_for_each_entry_safe(pos, next, &dev->ctrl_rd_list.list, list) {
		cl = pos->cl;
@@ -458,7 +483,7 @@ static void mei_hbm_cl_disconnect_res(struct mei_device *dev,
		dev_dbg(&dev->pdev->dev, "list_for_each_entry_safe in ctrl_rd_list.\n");
		if (mei_hbm_cl_addr_equal(cl, rs)) {
			list_del(&pos->list);
			if (!rs->status)
			if (rs->status == MEI_CL_DISCONN_SUCCESS)
				cl->state = MEI_FILE_DISCONNECTED;

			cl->status = 0;
@@ -500,14 +525,9 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
	struct mei_cl *cl;
	struct mei_cl_cb *pos = NULL, *next = NULL;

	dev_dbg(&dev->pdev->dev,
			"connect_response:\n"
			"ME Client = %d\n"
			"Host Client = %d\n"
			"Status = %d\n",
			rs->me_addr,
			rs->host_addr,
			rs->status);
	dev_dbg(&dev->pdev->dev, "hbm: connect response cl:host=%02d me=%02d status=%s\n",
			rs->me_addr, rs->host_addr,
			mei_cl_conn_status_str(rs->status));

	/* if WD or iamthif client treat specially */

@@ -532,7 +552,6 @@ static void mei_hbm_cl_connect_res(struct mei_device *dev,
		if (pos->fop_type == MEI_FOP_CONNECT) {
			if (is_treat_specially_client(cl, rs)) {
				list_del(&pos->list);
				cl->status = 0;
				cl->timer_count = 0;
				break;
			}
+8 −8
Original line number Diff line number Diff line
@@ -89,19 +89,19 @@ enum mei_stop_reason_types {
 * Client Connect Status
 * used by hbm_client_connect_response.status
 */
enum client_connect_status_types {
	CCS_SUCCESS = 0x00,
	CCS_NOT_FOUND = 0x01,
	CCS_ALREADY_STARTED = 0x02,
	CCS_OUT_OF_RESOURCES = 0x03,
	CCS_MESSAGE_SMALL = 0x04
enum mei_cl_connect_status {
	MEI_CL_CONN_SUCCESS          = 0x00,
	MEI_CL_CONN_NOT_FOUND        = 0x01,
	MEI_CL_CONN_ALREADY_STARTED  = 0x02,
	MEI_CL_CONN_OUT_OF_RESOURCES = 0x03,
	MEI_CL_CONN_MESSAGE_SMALL    = 0x04
};

/*
 * Client Disconnect Status
 */
enum client_disconnect_status_types {
	CDS_SUCCESS = 0x00
enum  mei_cl_disconnect_status {
	MEI_CL_DISCONN_SUCCESS = 0x00
};

/*
+1 −1
Original line number Diff line number Diff line
@@ -471,7 +471,7 @@ static int mei_ioctl_connect_client(struct file *file,
	if (i < 0 || dev->me_clients[i].props.fixed_address) {
		dev_dbg(&dev->pdev->dev, "Cannot connect to FW Client UUID = %pUl\n",
				&data->in_client_uuid);
		rets = -ENODEV;
		rets = -ENOTTY;
		goto end;
	}