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

Commit d2dfe6df authored by Reinette Chatre's avatar Reinette Chatre Committed by John W. Linville
Browse files

iwlwifi: enable serialization of synchronous commands



Until now it was only possible to have one synchronous command running at
any time. If a synchronous command is in progress when a second request
arrives then the second command will fail. Create a new mutex specific for
this purpose to only allow one synchronous command at a time, but enable
other commands to wait instead of fail if a synchronous command is in
progress.

Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 4a6547c7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3364,6 +3364,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
	INIT_LIST_HEAD(&priv->free_frames);

	mutex_init(&priv->mutex);
	mutex_init(&priv->sync_cmd_mutex);

	/* Clear the driver's (not device's) station table */
	iwl_clear_stations_table(priv);
+1 −1
Original line number Diff line number Diff line
@@ -603,7 +603,7 @@ void iwlcore_free_geos(struct iwl_priv *priv);
/*************** DRIVER STATUS FUNCTIONS   *****/

#define STATUS_HCMD_ACTIVE	0	/* host command in progress */
#define STATUS_HCMD_SYNC_ACTIVE	1	/* sync host command in progress */
/* 1 is unused (used to be STATUS_HCMD_SYNC_ACTIVE) */
#define STATUS_INT_ENABLED	2
#define STATUS_RF_KILL_HW	3
#define STATUS_CT_KILL		4
+0 −2
Original line number Diff line number Diff line
@@ -530,8 +530,6 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,

	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n",
		test_bit(STATUS_HCMD_ACTIVE, &priv->status));
	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n",
		test_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status));
	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n",
		test_bit(STATUS_INT_ENABLED, &priv->status));
	pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n",
+1 −0
Original line number Diff line number Diff line
@@ -1111,6 +1111,7 @@ struct iwl_priv {
	spinlock_t hcmd_lock;	/* protect hcmd */
	spinlock_t reg_lock;	/* protect hw register access */
	struct mutex mutex;
	struct mutex sync_cmd_mutex; /* enable serialization of sync commands */

	/* basic pci-network driver stuff */
	struct pci_dev *pci_dev;
+7 −7
Original line number Diff line number Diff line
@@ -164,15 +164,13 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
	 /* A synchronous command can not have a callback set. */
	BUG_ON(cmd->callback);

	if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
		IWL_ERR(priv,
			"Error sending %s: Already sending a host command\n",
	IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
			get_cmd_string(cmd->id));
		ret = -EBUSY;
		goto out;
	}
	mutex_lock(&priv->sync_cmd_mutex);

	set_bit(STATUS_HCMD_ACTIVE, &priv->status);
	IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s \n",
			get_cmd_string(cmd->id));

	cmd_idx = iwl_enqueue_hcmd(priv, cmd);
	if (cmd_idx < 0) {
@@ -193,6 +191,8 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
				jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));

			clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
			IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n",
				       get_cmd_string(cmd->id));
			ret = -ETIMEDOUT;
			goto cancel;
		}
@@ -237,7 +237,7 @@ fail:
		cmd->reply_page = 0;
	}
out:
	clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
	mutex_unlock(&priv->sync_cmd_mutex);
	return ret;
}
EXPORT_SYMBOL(iwl_send_cmd_sync);
Loading