|
@@ -1270,6 +1270,8 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, u32 txq_bm)
|
|
|
|
|
|
/* waiting for all the tx frames complete might take a while */
|
|
/* waiting for all the tx frames complete might take a while */
|
|
for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) {
|
|
for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) {
|
|
|
|
+ u8 wr_ptr;
|
|
|
|
+
|
|
if (cnt == trans_pcie->cmd_queue)
|
|
if (cnt == trans_pcie->cmd_queue)
|
|
continue;
|
|
continue;
|
|
if (!test_bit(cnt, trans_pcie->queue_used))
|
|
if (!test_bit(cnt, trans_pcie->queue_used))
|
|
@@ -1278,9 +1280,19 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, u32 txq_bm)
|
|
continue;
|
|
continue;
|
|
txq = &trans_pcie->txq[cnt];
|
|
txq = &trans_pcie->txq[cnt];
|
|
q = &txq->q;
|
|
q = &txq->q;
|
|
- while (q->read_ptr != q->write_ptr && !time_after(jiffies,
|
|
|
|
- now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS)))
|
|
|
|
|
|
+ wr_ptr = ACCESS_ONCE(q->write_ptr);
|
|
|
|
+
|
|
|
|
+ while (q->read_ptr != ACCESS_ONCE(q->write_ptr) &&
|
|
|
|
+ !time_after(jiffies,
|
|
|
|
+ now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS))) {
|
|
|
|
+ u8 write_ptr = ACCESS_ONCE(q->write_ptr);
|
|
|
|
+
|
|
|
|
+ if (WARN_ONCE(wr_ptr != write_ptr,
|
|
|
|
+ "WR pointer moved while flushing %d -> %d\n",
|
|
|
|
+ wr_ptr, write_ptr))
|
|
|
|
+ return -ETIMEDOUT;
|
|
msleep(1);
|
|
msleep(1);
|
|
|
|
+ }
|
|
|
|
|
|
if (q->read_ptr != q->write_ptr) {
|
|
if (q->read_ptr != q->write_ptr) {
|
|
IWL_ERR(trans,
|
|
IWL_ERR(trans,
|