qeth: postpone open till recovery is finished
authorUrsula Braun <ursula.braun@de.ibm.com>
Wed, 12 Jan 2011 20:42:24 +0000 (20:42 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 16 Jan 2011 04:45:56 +0000 (20:45 -0800)
The open function of qeth is not executed if the qeth device is in
state DOWN or HARDSETUP. A recovery switches from state SOFTSETUP to
HARDSETUP to DOWN to HARDSETUP and back to SOFTSETUP. If open and
recover are running concurrently, open fails if it hits the states
HARDSETUP or DOWN. This patch inserts waiting for recovery finish
in the qeth open functions to enable successful qeth device opening
in spite of a running recovery.

Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c

index 7a7a1b664781073aa09d10bfa134a1d9b8eb6b09..2ac8f6aff5a478e3bb34051aeacf3d9128890024 100644 (file)
@@ -831,12 +831,14 @@ tx_drop:
        return NETDEV_TX_OK;
 }
 
-static int qeth_l2_open(struct net_device *dev)
+static int __qeth_l2_open(struct net_device *dev)
 {
        struct qeth_card *card = dev->ml_priv;
        int rc = 0;
 
        QETH_CARD_TEXT(card, 4, "qethopen");
+       if (card->state == CARD_STATE_UP)
+               return rc;
        if (card->state != CARD_STATE_SOFTSETUP)
                return -ENODEV;
 
@@ -857,6 +859,18 @@ static int qeth_l2_open(struct net_device *dev)
        return rc;
 }
 
+static int qeth_l2_open(struct net_device *dev)
+{
+       struct qeth_card *card = dev->ml_priv;
+
+       QETH_CARD_TEXT(card, 5, "qethope_");
+       if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+               QETH_CARD_TEXT(card, 3, "openREC");
+               return -ERESTARTSYS;
+       }
+       return __qeth_l2_open(dev);
+}
+
 static int qeth_l2_stop(struct net_device *dev)
 {
        struct qeth_card *card = dev->ml_priv;
@@ -1046,7 +1060,7 @@ contin:
        if (recover_flag == CARD_STATE_RECOVER) {
                if (recovery_mode &&
                    card->info.type != QETH_CARD_TYPE_OSN) {
-                       qeth_l2_open(card->dev);
+                       __qeth_l2_open(card->dev);
                } else {
                        rtnl_lock();
                        dev_open(card->dev);
index e227e465bfc4686047e9f18f111681dfa6672364..988255b443e40e2bff6629674207eaa46b7453e5 100644 (file)
@@ -3240,12 +3240,14 @@ tx_drop:
        return NETDEV_TX_OK;
 }
 
-static int qeth_l3_open(struct net_device *dev)
+static int __qeth_l3_open(struct net_device *dev)
 {
        struct qeth_card *card = dev->ml_priv;
        int rc = 0;
 
        QETH_CARD_TEXT(card, 4, "qethopen");
+       if (card->state == CARD_STATE_UP)
+               return rc;
        if (card->state != CARD_STATE_SOFTSETUP)
                return -ENODEV;
        card->data.state = CH_STATE_UP;
@@ -3260,6 +3262,18 @@ static int qeth_l3_open(struct net_device *dev)
        return rc;
 }
 
+static int qeth_l3_open(struct net_device *dev)
+{
+       struct qeth_card *card = dev->ml_priv;
+
+       QETH_CARD_TEXT(card, 5, "qethope_");
+       if (qeth_wait_for_threads(card, QETH_RECOVER_THREAD)) {
+               QETH_CARD_TEXT(card, 3, "openREC");
+               return -ERESTARTSYS;
+       }
+       return __qeth_l3_open(dev);
+}
+
 static int qeth_l3_stop(struct net_device *dev)
 {
        struct qeth_card *card = dev->ml_priv;
@@ -3564,7 +3578,7 @@ contin:
                netif_carrier_off(card->dev);
        if (recover_flag == CARD_STATE_RECOVER) {
                if (recovery_mode)
-                       qeth_l3_open(card->dev);
+                       __qeth_l3_open(card->dev);
                else {
                        rtnl_lock();
                        dev_open(card->dev);