aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2020-11-13 22:22:52 +0100
committerKalle Valo <kvalo@codeaurora.org>2020-11-24 17:01:19 +0200
commita3d8a2599d47164a52af0d8ae2b50e60d41b2d75 (patch)
treeaa3507c12d36d65399c8e8b95ca1efbdb12e72aa /drivers/net/wireless/intersil/orinoco/orinoco_usb.c
parentorinoco: Annotate ezusb_docmd_wait() (diff)
downloadwireguard-linux-a3d8a2599d47164a52af0d8ae2b50e60d41b2d75.tar.xz
wireguard-linux-a3d8a2599d47164a52af0d8ae2b50e60d41b2d75.zip
orinoco: Annotate ezusb_read_ltv()
ezusb_read_ltv() is always invoked via the ->read_ltv() callback. This callback is mostly invoked under orinoco_lock() which disables BH. There are a few invocations during probe which occur in preemptible context via: ezusb_probe() -> orinoco_init() -> determine_fw_capabilities() Extend `hermes_ops' with the ->read_ltv_pr callback which is implemented with the same callback like ->read_ltv on `hermes_ops_local'. On `ezusb_ops' ->read_ltv is used for callbacks under the lock which need to poll. The new ->read_ltv_pr() is used in the preemptible context in which it is possible to wait for the completion. Provide HERMES_READ_RECORD_PR() and hermes_read_wordrec_pr() which behave like their non _pr equivalents and invoke ->read_ltv_pr(). This removes the last user of ezusb_req_ctx_wait() and can now be removed. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/20201113212252.2243570-11-bigeasy@linutronix.de
Diffstat (limited to 'drivers/net/wireless/intersil/orinoco/orinoco_usb.c')
-rw-r--r--drivers/net/wireless/intersil/orinoco/orinoco_usb.c49
1 files changed, 20 insertions, 29 deletions
diff --git a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
index 4c60b4821463..dd31929261ab 100644
--- a/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/intersil/orinoco/orinoco_usb.c
@@ -667,32 +667,6 @@ static void ezusb_request_in_callback(struct ezusb_priv *upriv,
typedef void (*ezusb_ctx_wait)(struct ezusb_priv *, struct request_context *);
-static void ezusb_req_ctx_wait(struct ezusb_priv *upriv,
- struct request_context *ctx)
-{
- switch (ctx->state) {
- case EZUSB_CTX_QUEUED:
- case EZUSB_CTX_REQ_SUBMITTED:
- case EZUSB_CTX_REQ_COMPLETE:
- case EZUSB_CTX_RESP_RECEIVED:
- if (in_softirq()) {
- /* If we get called from a timer, timeout timers don't
- * get the chance to run themselves. So we make sure
- * that we don't sleep for ever */
- int msecs = DEF_TIMEOUT * (1000 / HZ);
-
- while (!try_wait_for_completion(&ctx->done) && msecs--)
- udelay(1000);
- } else {
- wait_for_completion(&ctx->done);
- }
- break;
- default:
- /* Done or failed - nothing to wait for */
- break;
- }
-}
-
static void ezusb_req_ctx_wait_compl(struct ezusb_priv *upriv,
struct request_context *ctx)
{
@@ -1032,8 +1006,10 @@ static int ezusb_write_ltv(struct hermes *hw, int bap, u16 rid,
ezusb_req_ctx_wait_poll);
}
-static int ezusb_read_ltv(struct hermes *hw, int bap, u16 rid,
- unsigned bufsize, u16 *length, void *buf)
+static int __ezusb_read_ltv(struct hermes *hw, int bap, u16 rid,
+ unsigned bufsize, u16 *length, void *buf,
+ ezusb_ctx_wait ezusb_ctx_wait_func)
+
{
struct ezusb_priv *upriv = hw->priv;
struct request_context *ctx;
@@ -1046,7 +1022,21 @@ static int ezusb_read_ltv(struct hermes *hw, int bap, u16 rid,
return -ENOMEM;
return ezusb_access_ltv(upriv, ctx, 0, NULL, EZUSB_FRAME_CONTROL,
- buf, bufsize, length, ezusb_req_ctx_wait);
+ buf, bufsize, length, ezusb_req_ctx_wait_poll);
+}
+
+static int ezusb_read_ltv(struct hermes *hw, int bap, u16 rid,
+ unsigned bufsize, u16 *length, void *buf)
+{
+ return __ezusb_read_ltv(hw, bap, rid, bufsize, length, buf,
+ ezusb_req_ctx_wait_poll);
+}
+
+static int ezusb_read_ltv_preempt(struct hermes *hw, int bap, u16 rid,
+ unsigned bufsize, u16 *length, void *buf)
+{
+ return __ezusb_read_ltv(hw, bap, rid, bufsize, length, buf,
+ ezusb_req_ctx_wait_compl);
}
static int ezusb_doicmd_wait(struct hermes *hw, u16 cmd, u16 parm0, u16 parm1,
@@ -1586,6 +1576,7 @@ static const struct hermes_ops ezusb_ops = {
.init_cmd_wait = ezusb_doicmd_wait,
.allocate = ezusb_allocate,
.read_ltv = ezusb_read_ltv,
+ .read_ltv_pr = ezusb_read_ltv_preempt,
.write_ltv = ezusb_write_ltv,
.bap_pread = ezusb_bap_pread,
.read_pda = ezusb_read_pda,