summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorManish Chopra <manish.chopra@qlogic.com>2013-08-15 08:27:26 -0400
committerDavid S. Miller <davem@davemloft.net>2013-08-15 14:46:18 -0700
commit35570cfefd15d89ede00ce550e06acbcac3b3098 (patch)
treef0dbc5150b7467f15efce2dad5ba14c393e502b3 /drivers
parent91b86e3dd00862c6ed36691c849762949aaa833e (diff)
qlcnic: Flush mailbox command list when mailbox is not available
o Driver was hitting a panic at the time of adapter reset due to invalid command access from the list which had been already freed by the queuing thread. Flush all the pending commands from the list before proceeding with adapter reset Signed-off-by: Manish Chopra <manish.chopra@qlogic.com> Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index 55a597799cf8..43b51a0ebb45 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -3515,6 +3515,8 @@ static inline void qlcnic_83xx_flush_mbx_queue(struct qlcnic_adapter *adapter)
while (!list_empty(head)) {
cmd = list_entry(head->next, struct qlcnic_cmd_args, list);
+ dev_info(&adapter->pdev->dev, "%s: Mailbox command 0x%x\n",
+ __func__, cmd->cmd_op);
list_del(&cmd->list);
mbx->num_cmds--;
qlcnic_83xx_notify_cmd_completion(adapter, cmd);
@@ -3534,6 +3536,7 @@ static inline int qlcnic_83xx_check_mbx_status(struct qlcnic_adapter *adapter)
host_mbx_ctrl = QLCRDX(ahw, QLCNIC_HOST_MBX_CTRL);
if (host_mbx_ctrl) {
+ clear_bit(QLC_83XX_MBX_READY, &mbx->status);
ahw->idc.collect_dump = 1;
return -EIO;
}
@@ -3704,8 +3707,10 @@ static void qlcnic_83xx_mailbox_worker(struct work_struct *work)
ahw = adapter->ahw;
while (true) {
- if (qlcnic_83xx_check_mbx_status(adapter))
+ if (qlcnic_83xx_check_mbx_status(adapter)) {
+ qlcnic_83xx_flush_mbx_queue(adapter);
return;
+ }
atomic_set(rsp_status, QLC_83XX_MBX_RESPONSE_WAIT);