diff options
author | Sebastian Andrzej Siewior <bigeasy@linutronix.de> | 2020-11-13 22:22:52 +0100 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2020-11-24 17:01:19 +0200 |
commit | a3d8a2599d47164a52af0d8ae2b50e60d41b2d75 (patch) | |
tree | aa3507c12d36d65399c8e8b95ca1efbdb12e72aa /drivers/net/wireless/intersil/orinoco/orinoco_usb.c | |
parent | a9a2678abacbcae902b4fb4bc5585a621099cc06 (diff) | |
download | linux-a3d8a2599d47164a52af0d8ae2b50e60d41b2d75.tar.gz linux-a3d8a2599d47164a52af0d8ae2b50e60d41b2d75.tar.bz2 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.c | 49 |
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, |