mei: fixed address clients for the new platforms
authorAlexander Usyskin <alexander.usyskin@intel.com>
Sun, 7 Feb 2016 21:35:38 +0000 (23:35 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 7 Feb 2016 22:47:20 +0000 (14:47 -0800)
Enable by default connection to fixed address clients
from user-space for skylake and newer platform.

Signed-off-by: Alexander Usyskin <alexander.usyskin@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/mei/debugfs.c
drivers/misc/mei/hbm.c
drivers/misc/mei/hw.h
drivers/misc/mei/main.c
drivers/misc/mei/mei_dev.h

index 6bdd754..8ad4063 100644 (file)
@@ -176,6 +176,8 @@ static ssize_t mei_dbgfs_read_devstate(struct file *fp, char __user *ubuf,
                                 dev->hbm_f_dot_supported);
                pos += scnprintf(buf + pos, bufsz - pos, "\tEV: %01d\n",
                                 dev->hbm_f_ev_supported);
+               pos += scnprintf(buf + pos, bufsz - pos, "\tFA: %01d\n",
+                                dev->hbm_f_fa_supported);
        }
 
        pos += scnprintf(buf + pos, bufsz - pos, "pg:  %s, %s\n",
@@ -191,6 +193,30 @@ static const struct file_operations mei_dbgfs_fops_devstate = {
        .llseek = generic_file_llseek,
 };
 
+static ssize_t mei_dbgfs_write_allow_fa(struct file *file,
+                                       const char __user *user_buf,
+                                       size_t count, loff_t *ppos)
+{
+       struct mei_device *dev;
+       int ret;
+
+       dev = container_of(file->private_data,
+                          struct mei_device, allow_fixed_address);
+
+       ret = debugfs_write_file_bool(file, user_buf, count, ppos);
+       if (ret < 0)
+               return ret;
+       dev->override_fixed_address = true;
+       return ret;
+}
+
+static const struct file_operations mei_dbgfs_fops_allow_fa = {
+       .open = simple_open,
+       .read = debugfs_read_file_bool,
+       .write = mei_dbgfs_write_allow_fa,
+       .llseek = generic_file_llseek,
+};
+
 /**
  * mei_dbgfs_deregister - Remove the debugfs files and directories
  *
@@ -240,8 +266,9 @@ int mei_dbgfs_register(struct mei_device *dev, const char *name)
                dev_err(dev->dev, "devstate: registration failed\n");
                goto err;
        }
-       f = debugfs_create_bool("allow_fixed_address", S_IRUSR | S_IWUSR, dir,
-                               &dev->allow_fixed_address);
+       f = debugfs_create_file("allow_fixed_address", S_IRUSR | S_IWUSR, dir,
+                               &dev->allow_fixed_address,
+                               &mei_dbgfs_fops_allow_fa);
        if (!f) {
                dev_err(dev->dev, "allow_fixed_address: registration failed\n");
                goto err;
index e7b7aad..3915b8e 100644 (file)
@@ -979,6 +979,10 @@ static void mei_hbm_config_features(struct mei_device *dev)
        /* Notification Event Support */
        if (dev->version.major_version >= HBM_MAJOR_VERSION_EV)
                dev->hbm_f_ev_supported = 1;
+
+       /* Fixed Address Client Support */
+       if (dev->version.major_version >= HBM_MAJOR_VERSION_FA)
+               dev->hbm_f_fa_supported = 1;
 }
 
 /**
index 4c5d6cf..459ad59 100644 (file)
 #define HBM_MINOR_VERSION_EV               0
 #define HBM_MAJOR_VERSION_EV               2
 
+/*
+ * MEI version with fixed address client support
+ */
+#define HBM_MINOR_VERSION_FA               0
+#define HBM_MAJOR_VERSION_FA               2
+
 /* Host bus message command opcode */
 #define MEI_HBM_CMD_OP_MSK                  0x7f
 /* Host bus message command RESPONSE */
index f1fdd65..58fa2c8 100644 (file)
@@ -369,12 +369,22 @@ static int mei_ioctl_connect_client(struct file *file,
 
        /* find ME client we're trying to connect to */
        me_cl = mei_me_cl_by_uuid(dev, &data->in_client_uuid);
-       if (!me_cl ||
-           (me_cl->props.fixed_address && !dev->allow_fixed_address)) {
+       if (!me_cl) {
                dev_dbg(dev->dev, "Cannot connect to FW Client UUID = %pUl\n",
                        &data->in_client_uuid);
-               mei_me_cl_put(me_cl);
-               return  -ENOTTY;
+               rets = -ENOTTY;
+               goto end;
+       }
+
+       if (me_cl->props.fixed_address) {
+               bool forbidden = dev->override_fixed_address ?
+                        !dev->allow_fixed_address : !dev->hbm_f_fa_supported;
+               if (forbidden) {
+                       dev_dbg(dev->dev, "Connection forbidden to FW Client UUID = %pUl\n",
+                               &data->in_client_uuid);
+                       rets = -ENOTTY;
+                       goto end;
+               }
        }
 
        dev_dbg(dev->dev, "Connect to FW Client ID = %d\n",
index 70c4da0..6d97f33 100644 (file)
@@ -396,6 +396,7 @@ const char *mei_pg_state_str(enum mei_pg_state state);
  * @hbm_f_dc_supported  : hbm feature dynamic clients
  * @hbm_f_dot_supported : hbm feature disconnect on timeout
  * @hbm_f_ev_supported  : hbm feature event notification
+ * @hbm_f_fa_supported  : hbm feature fixed address client
  *
  * @me_clients_rwsem: rw lock over me_clients list
  * @me_clients  : list of FW clients
@@ -404,6 +405,7 @@ const char *mei_pg_state_str(enum mei_pg_state state);
  * @me_client_index : last FW client index in enumeration
  *
  * @allow_fixed_address: allow user space to connect a fixed client
+ * @override_fixed_address: force allow fixed address behavior
  *
  * @amthif_cmd_list : amthif list for cmd waiting
  * @iamthif_fp : file for current amthif operation
@@ -483,6 +485,7 @@ struct mei_device {
        unsigned int hbm_f_dc_supported:1;
        unsigned int hbm_f_dot_supported:1;
        unsigned int hbm_f_ev_supported:1;
+       unsigned int hbm_f_fa_supported:1;
 
        struct rw_semaphore me_clients_rwsem;
        struct list_head me_clients;
@@ -491,6 +494,7 @@ struct mei_device {
        unsigned long me_client_index;
 
        bool allow_fixed_address;
+       bool override_fixed_address;
 
        /* amthif list for cmd waiting */
        struct mei_cl_cb amthif_cmd_list;