On Thu, Oct 17, 2013 at 11:06:55AM +0200, Stanislaw Gruszka wrote: > Sorry for late answer. I have two more patches, which perhaps make > powersave stop crashing on 3945. Please test them (note that I only > compile tested, be carefull :-) First patch has a bug. I'm attaching improved version. Stanislaw
>From dae9f167853f266d5efe688f965968725375e2ae Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka <sgruszka@xxxxxxxxxx> Date: Thu, 17 Oct 2013 15:30:07 +0200 Subject: [PATCH] iwlegacy poke device when waiting for hcmd Signed-off-by: Stanislaw Gruszka <sgruszka@xxxxxxxxxx> --- drivers/net/wireless/iwlegacy/common.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c index b03e22e..3d8dae3c 100644 --- a/drivers/net/wireless/iwlegacy/common.c +++ b/drivers/net/wireless/iwlegacy/common.c @@ -254,8 +254,6 @@ il_get_cmd_string(u8 cmd) } EXPORT_SYMBOL(il_get_cmd_string); -#define HOST_COMPLETE_TIMEOUT (HZ / 2) - static void il_generic_cmd_callback(struct il_priv *il, struct il_device_cmd *cmd, struct il_rx_pkt *pkt) @@ -305,11 +303,15 @@ il_send_cmd_async(struct il_priv *il, struct il_host_cmd *cmd) return 0; } +#define HOST_COMPLETE_TIMEOUT (HZ / 2) +#define COMMAND_POKE_TIMEOUT (HZ / 10) + int il_send_cmd_sync(struct il_priv *il, struct il_host_cmd *cmd) { - int cmd_idx; - int ret; + unsigned long flags; + int cmd_idx, ret; + int timeout = HOST_COMPLETE_TIMEOUT; lockdep_assert_held(&il->mutex); @@ -333,9 +335,22 @@ il_send_cmd_sync(struct il_priv *il, struct il_host_cmd *cmd) goto out; } - ret = wait_event_timeout(il->wait_command_queue, - !test_bit(S_HCMD_ACTIVE, &il->status), - HOST_COMPLETE_TIMEOUT); + while (timeout > 0) { + ret = wait_event_timeout(il->wait_command_queue, + !test_bit(S_HCMD_ACTIVE, &il->status), + COMMAND_POKE_TIMEOUT); + if (ret) + break; + + /* Poke the device, it may have lost the command. */ + spin_lock_irqsave(&il->reg_lock, flags); + _il_grab_nic_access(il); + _il_release_nic_access(il); + spin_unlock_irqrestore(&il->reg_lock, flags); + + timeout -= COMMAND_POKE_TIMEOUT; + } + if (!ret) { if (test_bit(S_HCMD_ACTIVE, &il->status)) { IL_ERR("Error sending %s: time out after %dms.\n", -- 1.8.3.1