浏览代码

qeth: do not spin for SETIP ip assist command

The ip assist hw command for setting an IP address last unacceptable
long so we can not spin while we waiting for the irq. Since we can
ensure process context for all occurrences of this command we can use
wait.

Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Frank Blaschka 16 年之前
父节点
当前提交
5b54e16f1a
共有 1 个文件被更改,包括 29 次插入11 次删除
  1. 29 11
      drivers/s390/net/qeth_core_main.c

+ 29 - 11
drivers/s390/net/qeth_core_main.c

@@ -1685,6 +1685,7 @@ int qeth_send_control_data(struct qeth_card *card, int len,
 	unsigned long flags;
 	unsigned long flags;
 	struct qeth_reply *reply = NULL;
 	struct qeth_reply *reply = NULL;
 	unsigned long timeout;
 	unsigned long timeout;
+	struct qeth_ipa_cmd *cmd;
 
 
 	QETH_DBF_TEXT(TRACE, 2, "sendctl");
 	QETH_DBF_TEXT(TRACE, 2, "sendctl");
 
 
@@ -1731,17 +1732,34 @@ int qeth_send_control_data(struct qeth_card *card, int len,
 		wake_up(&card->wait_q);
 		wake_up(&card->wait_q);
 		return rc;
 		return rc;
 	}
 	}
-	while (!atomic_read(&reply->received)) {
-		if (time_after(jiffies, timeout)) {
-			spin_lock_irqsave(&reply->card->lock, flags);
-			list_del_init(&reply->list);
-			spin_unlock_irqrestore(&reply->card->lock, flags);
-			reply->rc = -ETIME;
-			atomic_inc(&reply->received);
-			wake_up(&reply->wait_q);
-		}
-		cpu_relax();
-	};
+
+	/* we have only one long running ipassist, since we can ensure
+	   process context of this command we can sleep */
+	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
+	if ((cmd->hdr.command == IPA_CMD_SETIP) &&
+	    (cmd->hdr.prot_version == QETH_PROT_IPV4)) {
+		if (!wait_event_timeout(reply->wait_q,
+		    atomic_read(&reply->received), timeout))
+			goto time_err;
+	} else {
+		while (!atomic_read(&reply->received)) {
+			if (time_after(jiffies, timeout))
+				goto time_err;
+			cpu_relax();
+		};
+	}
+
+	rc = reply->rc;
+	qeth_put_reply(reply);
+	return rc;
+
+time_err:
+	spin_lock_irqsave(&reply->card->lock, flags);
+	list_del_init(&reply->list);
+	spin_unlock_irqrestore(&reply->card->lock, flags);
+	reply->rc = -ETIME;
+	atomic_inc(&reply->received);
+	wake_up(&reply->wait_q);
 	rc = reply->rc;
 	rc = reply->rc;
 	qeth_put_reply(reply);
 	qeth_put_reply(reply);
 	return rc;
 	return rc;