diff mbox series

[30/31] staging: wfx: drop async field from struct hif_cmd

Message ID 20200907101521.66082-31-Jerome.Pouiller@silabs.com
State New
Headers show
Series [01/31] staging: wfx: improve readability of association processing | expand

Commit Message

Jérôme Pouiller Sept. 7, 2020, 10:15 a.m. UTC
From: Jérôme Pouiller <jerome.pouiller@silabs.com>

The parameter "async" in wfx_cmd_send() allows to send command without
waiting for the reply. In this case, the mutex hif_cmd.lock is released
asynchronously in the context of the receiver workqueue.

However, "kbuild test robot" complains about this architecture[1] since
it is not able to follow the lock duration of hif_cmd.lock (and indeed,
the state of the driver if the hardware wouldn't reply is not well
defined).

Besides, this feature is not really necessary. It is only used by
hif_shutdown(). This function hijack the 'async' flag to run a command
that won't answer.

So, this patch removes the 'async' flag and introduces a 'no_reply' flag.
Thus, the mutex hif_cmd.lock is only acquired/released from
hif_cmd_send(). Therefore:
  - hif_shutdown() does not have to touch the private data of the struct
    hif_cmd
  - Kbuild test robot should be happy
  - the resulting code is simpler

[1] https://lore.kernel.org/driverdev-devel/alpine.DEB.2.21.1910041317381.2992@hadrien/

Reported-by: kbuild test robot <lkp@intel.com>
Reported-by: Julia Lawall <julia.lawall@lip6.fr>
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
---
 drivers/staging/wfx/hif_rx.c |  7 +------
 drivers/staging/wfx/hif_tx.c | 24 +++++++++---------------
 drivers/staging/wfx/hif_tx.h |  1 -
 3 files changed, 10 insertions(+), 22 deletions(-)
diff mbox series

Patch

diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c
index 6950b3e9d7cf..b40af86356f1 100644
--- a/drivers/staging/wfx/hif_rx.c
+++ b/drivers/staging/wfx/hif_rx.c
@@ -47,12 +47,7 @@  static int hif_generic_confirm(struct wfx_dev *wdev,
 	}
 	wdev->hif_cmd.ret = status;
 
-	if (!wdev->hif_cmd.async) {
-		complete(&wdev->hif_cmd.done);
-	} else {
-		wdev->hif_cmd.buf_send = NULL;
-		mutex_unlock(&wdev->hif_cmd.lock);
-	}
+	complete(&wdev->hif_cmd.done);
 	return status;
 }
 
diff --git a/drivers/staging/wfx/hif_tx.c b/drivers/staging/wfx/hif_tx.c
index a75c6b9804ba..1bd7f773209c 100644
--- a/drivers/staging/wfx/hif_tx.c
+++ b/drivers/staging/wfx/hif_tx.c
@@ -47,7 +47,7 @@  static void *wfx_alloc_hif(size_t body_len, struct hif_msg **hif)
 }
 
 int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request,
-		 void *reply, size_t reply_len, bool async)
+		 void *reply, size_t reply_len, bool no_reply)
 {
 	const char *mib_name = "";
 	const char *mib_sep = "";
@@ -55,8 +55,6 @@  int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request,
 	int vif = request->interface;
 	int ret;
 
-	WARN(wdev->hif_cmd.buf_recv && wdev->hif_cmd.async, "API usage error");
-
 	// Do not wait for any reply if chip is frozen
 	if (wdev->chip_frozen)
 		return -ETIMEDOUT;
@@ -69,14 +67,18 @@  int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request,
 	wdev->hif_cmd.buf_send = request;
 	wdev->hif_cmd.buf_recv = reply;
 	wdev->hif_cmd.len_recv = reply_len;
-	wdev->hif_cmd.async = async;
 	complete(&wdev->hif_cmd.ready);
 
 	wfx_bh_request_tx(wdev);
 
-	// NOTE: no timeout is caught async is enabled
-	if (async)
+	if (no_reply) {
+		// Chip won't reply. Give enough time to the wq to send the
+		// buffer.
+		msleep(100);
+		wdev->hif_cmd.buf_send = NULL;
+		mutex_unlock(&wdev->hif_cmd.lock);
 		return 0;
+	}
 
 	if (wdev->poll_irq)
 		wfx_bh_poll_irq(wdev);
@@ -118,29 +120,21 @@  int wfx_cmd_send(struct wfx_dev *wdev, struct hif_msg *request,
 }
 
 // This function is special. After HIF_REQ_ID_SHUT_DOWN, chip won't reply to any
-// request anymore. We need to slightly hack struct wfx_hif_cmd for that job. Be
-// careful to only call this function during device unregister.
+// request anymore. Obviously, only call this function during device unregister.
 int hif_shutdown(struct wfx_dev *wdev)
 {
 	int ret;
 	struct hif_msg *hif;
 
-	if (wdev->chip_frozen)
-		return 0;
 	wfx_alloc_hif(0, &hif);
 	if (!hif)
 		return -ENOMEM;
 	wfx_fill_header(hif, -1, HIF_REQ_ID_SHUT_DOWN, 0);
 	ret = wfx_cmd_send(wdev, hif, NULL, 0, true);
-	// After this command, chip won't reply. Be sure to give enough time to
-	// bh to send buffer:
-	msleep(100);
-	wdev->hif_cmd.buf_send = NULL;
 	if (wdev->pdata.gpio_wakeup)
 		gpiod_set_value(wdev->pdata.gpio_wakeup, 0);
 	else
 		control_reg_write(wdev, 0);
-	mutex_unlock(&wdev->hif_cmd.lock);
 	kfree(hif);
 	return ret;
 }
diff --git a/drivers/staging/wfx/hif_tx.h b/drivers/staging/wfx/hif_tx.h
index e8aca39e7497..960d5f2fa41c 100644
--- a/drivers/staging/wfx/hif_tx.h
+++ b/drivers/staging/wfx/hif_tx.h
@@ -22,7 +22,6 @@  struct wfx_hif_cmd {
 	struct mutex      lock;
 	struct completion ready;
 	struct completion done;
-	bool              async;
 	struct hif_msg    *buf_send;
 	void              *buf_recv;
 	size_t            len_recv;