Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 908abbb5 authored by Ursula Braun's avatar Ursula Braun Committed by David S. Miller
Browse files

qeth: avoid loop if ipa command response is missing



If qeth issues an ipa command, but for some reasons the response
never comes back, qeth reaches a timeout.
Reset the irq_pending flag of the write channel in timeout handling
code and trigger a recovery to avoid endless looping for the following
ipa command.

Signed-off-by: default avatarUrsula Braun <ursula.braun@de.ibm.com>
Signed-off-by: default avatarFrank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9dc48ccc
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -740,6 +740,7 @@ struct qeth_card {
	struct qeth_qdio_info qdio;
	struct qeth_perf_stats perf_stats;
	int use_hard_stop;
	int read_or_write_problem;
	struct qeth_osn_info osn_info;
	struct qeth_discipline discipline;
	atomic_t force_alloc_skb;
+15 −0
Original line number Diff line number Diff line
@@ -262,6 +262,7 @@ static int qeth_issue_next_read(struct qeth_card *card)
		QETH_DBF_MESSAGE(2, "%s error in starting next read ccw! "
			"rc=%i\n", dev_name(&card->gdev->dev), rc);
		atomic_set(&card->read.irq_pending, 0);
		card->read_or_write_problem = 1;
		qeth_schedule_recovery(card);
		wake_up(&card->wait_q);
	}
@@ -382,6 +383,7 @@ void qeth_clear_ipacmd_list(struct qeth_card *card)
		qeth_put_reply(reply);
	}
	spin_unlock_irqrestore(&card->lock, flags);
	atomic_set(&card->write.irq_pending, 0);
}
EXPORT_SYMBOL_GPL(qeth_clear_ipacmd_list);

@@ -1076,6 +1078,7 @@ static int qeth_setup_card(struct qeth_card *card)
	card->state = CARD_STATE_DOWN;
	card->lan_online = 0;
	card->use_hard_stop = 0;
	card->read_or_write_problem = 0;
	card->dev = NULL;
	spin_lock_init(&card->vlanlock);
	spin_lock_init(&card->mclock);
@@ -1658,6 +1661,10 @@ int qeth_send_control_data(struct qeth_card *card, int len,

	QETH_CARD_TEXT(card, 2, "sendctl");

	if (card->read_or_write_problem) {
		qeth_release_buffer(iob->channel, iob);
		return -EIO;
	}
	reply = qeth_alloc_reply(card);
	if (!reply) {
		return -ENOMEM;
@@ -1729,6 +1736,9 @@ time_err:
	spin_unlock_irqrestore(&reply->card->lock, flags);
	reply->rc = -ETIME;
	atomic_inc(&reply->received);
	atomic_set(&card->write.irq_pending, 0);
	qeth_release_buffer(iob->channel, iob);
	card->write.buf_no = (card->write.buf_no + 1) % QETH_CMD_BUFFER_NO;
	wake_up(&reply->wait_q);
	rc = reply->rc;
	qeth_put_reply(reply);
@@ -2485,6 +2495,10 @@ int qeth_send_ipa_cmd(struct qeth_card *card, struct qeth_cmd_buffer *iob,
	qeth_prepare_ipa_cmd(card, iob, prot_type);
	rc = qeth_send_control_data(card, IPA_CMD_LENGTH,
						iob, reply_cb, reply_param);
	if (rc == -ETIME) {
		qeth_clear_ipacmd_list(card);
		qeth_schedule_recovery(card);
	}
	return rc;
}
EXPORT_SYMBOL_GPL(qeth_send_ipa_cmd);
@@ -3967,6 +3981,7 @@ retriable:
		else
			goto retry;
	}
	card->read_or_write_problem = 0;
	rc = qeth_mpc_initialize(card);
	if (rc) {
		QETH_DBF_TEXT_(SETUP, 2, "5err%d", rc);