qeth: avoid qeth recovery problems
authorUrsula Braun <ursula.braun@de.ibm.com>
Fri, 19 Sep 2008 10:56:03 +0000 (12:56 +0200)
committerJeff Garzik <jgarzik@redhat.com>
Thu, 25 Sep 2008 00:47:57 +0000 (20:47 -0400)
Do not touch IFF_UP flag during qeth recovery, but invoke dev_close()
in case of failing recovery.
Cancel outstanding control commands in case of Data Checks or
Channel Checks.
Do not invoke qeth_l2_del_all_mc() in case of a hard stop to speed up
removal of qeth devices.

Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l2_main.c
drivers/s390/net/qeth_l3_main.c

index c7ab1b864516694e97eb3438a70b26f7a20fb952..908f50b17e269cfb6159cbf84a77c06abde7d50a 100644 (file)
@@ -760,7 +760,7 @@ static int qeth_get_problem(struct ccw_device *cdev, struct irb *irb)
                if (sense[SENSE_COMMAND_REJECT_BYTE] &
                    SENSE_COMMAND_REJECT_FLAG) {
                        QETH_DBF_TEXT(TRACE, 2, "CMDREJi");
-                       return 0;
+                       return 1;
                }
                if ((sense[2] == 0xaf) && (sense[3] == 0xfe)) {
                        QETH_DBF_TEXT(TRACE, 2, "AFFE");
@@ -884,6 +884,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm,
                }
                rc = qeth_get_problem(cdev, irb);
                if (rc) {
+                       qeth_clear_ipacmd_list(card);
                        qeth_schedule_recovery(card);
                        goto out;
                }
@@ -4147,6 +4148,7 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev)
        unsigned long flags;
        struct qeth_card *card = dev_get_drvdata(&gdev->dev);
 
+       QETH_DBF_TEXT(SETUP, 2, "removedv");
        if (card->discipline.ccwgdriver) {
                card->discipline.ccwgdriver->remove(gdev);
                qeth_core_free_discipline(card);
index 573b5e564edd450e3a44eb13b1967613c6ef6652..955ba7a31b90606dcdaa5309d781a2a27983e2a0 100644 (file)
@@ -395,7 +395,8 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
        }
        if (card->state == CARD_STATE_SOFTSETUP) {
                qeth_l2_process_vlans(card, 1);
-               qeth_l2_del_all_mc(card);
+               if (!card->use_hard_stop)
+                       qeth_l2_del_all_mc(card);
                qeth_clear_ipacmd_list(card);
                card->state = CARD_STATE_HARDSETUP;
        }
@@ -826,7 +827,6 @@ static int qeth_l2_open(struct net_device *dev)
        }
        card->data.state = CH_STATE_UP;
        card->state = CARD_STATE_UP;
-       card->dev->flags |= IFF_UP;
        netif_start_queue(dev);
 
        if (!card->lan_online && netif_carrier_ok(dev))
@@ -841,7 +841,6 @@ static int qeth_l2_stop(struct net_device *dev)
 
        QETH_DBF_TEXT(TRACE, 4, "qethstop");
        netif_tx_disable(dev);
-       card->dev->flags &= ~IFF_UP;
        if (card->state == CARD_STATE_UP)
                card->state = CARD_STATE_SOFTSETUP;
        return 0;
@@ -1138,9 +1137,13 @@ static int qeth_l2_recover(void *ptr)
        if (!rc)
                PRINT_INFO("Device %s successfully recovered!\n",
                           CARD_BUS_ID(card));
-       else
+       else {
+               rtnl_lock();
+               dev_close(card->dev);
+               rtnl_unlock();
                PRINT_INFO("Device %s could not be recovered!\n",
                           CARD_BUS_ID(card));
+       }
        return 0;
 }
 
index dd72c3c2016520fddfa81b943e5025d7a16f4398..99547dea44de1997eb91fd31690af0ffec89f8d9 100644 (file)
@@ -2795,7 +2795,6 @@ static int qeth_l3_open(struct net_device *dev)
                return -ENODEV;
        card->data.state = CH_STATE_UP;
        card->state = CARD_STATE_UP;
-       card->dev->flags |= IFF_UP;
        netif_start_queue(dev);
 
        if (!card->lan_online && netif_carrier_ok(dev))
@@ -2809,7 +2808,6 @@ static int qeth_l3_stop(struct net_device *dev)
 
        QETH_DBF_TEXT(TRACE, 4, "qethstop");
        netif_tx_disable(dev);
-       card->dev->flags &= ~IFF_UP;
        if (card->state == CARD_STATE_UP)
                card->state = CARD_STATE_SOFTSETUP;
        return 0;
@@ -3218,9 +3216,13 @@ static int qeth_l3_recover(void *ptr)
        if (!rc)
                PRINT_INFO("Device %s successfully recovered!\n",
                           CARD_BUS_ID(card));
-       else
+       else {
+               rtnl_lock();
+               dev_close(card->dev);
+               rtnl_unlock();
                PRINT_INFO("Device %s could not be recovered!\n",
                           CARD_BUS_ID(card));
+       }
        return 0;
 }