--- /dev/null
+From: Gerald Schaefer <geraldsc@de.ibm.com>
+Subject: qeth: qeth recovery fails
+References: bnc#434333
+
+Symptom: Device is not functional after a recovery
+Problem: The handling of the IFF flags changed in 2.6.27 code
+Solution: 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>
+
+Acked-by: John Jolly <jjolly@suse.de>
+---
+
+ drivers/s390/net/qeth_core_main.c | 4 +++-
+ drivers/s390/net/qeth_l2_main.c | 11 +++++++----
+ drivers/s390/net/qeth_l3_main.c | 8 +++++---
+ 3 files changed, 15 insertions(+), 8 deletions(-)
+
+Index: linux-sles11/drivers/s390/net/qeth_core_main.c
+===================================================================
+--- linux-sles11.orig/drivers/s390/net/qeth_core_main.c
++++ linux-sles11/drivers/s390/net/qeth_core_main.c
+@@ -767,7 +767,7 @@ static int qeth_get_problem(struct ccw_d
+ 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");
+@@ -895,6 +895,7 @@ static void qeth_irq(struct ccw_device *
+ }
+ rc = qeth_get_problem(cdev, irb);
+ if (rc) {
++ qeth_clear_ipacmd_list(card);
+ qeth_schedule_recovery(card);
+ goto out;
+ }
+@@ -4160,6 +4161,7 @@ static void qeth_core_remove_device(stru
+ 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: linux-sles11/drivers/s390/net/qeth_l2_main.c
+===================================================================
+--- linux-sles11.orig/drivers/s390/net/qeth_l2_main.c
++++ linux-sles11/drivers/s390/net/qeth_l2_main.c
+@@ -397,7 +397,8 @@ static int qeth_l2_stop_card(struct qeth
+ }
+ 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;
+ }
+@@ -829,7 +830,6 @@ static int qeth_l2_open(struct net_devic
+ }
+ 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))
+@@ -844,7 +844,6 @@ static int qeth_l2_stop(struct net_devic
+
+ 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;
+@@ -1136,9 +1135,13 @@ static int qeth_l2_recover(void *ptr)
+ if (!rc)
+ dev_info(&card->gdev->dev,
+ "Device successfully recovered!\n");
+- else
++ else {
++ rtnl_lock();
++ dev_close(card->dev);
++ rtnl_unlock();
+ dev_warn(&card->gdev->dev, "The qeth device driver "
+ "failed to recover an error on the device\n");
++ }
+ return 0;
+ }
+
+Index: linux-sles11/drivers/s390/net/qeth_l3_main.c
+===================================================================
+--- linux-sles11.orig/drivers/s390/net/qeth_l3_main.c
++++ linux-sles11/drivers/s390/net/qeth_l3_main.c
+@@ -2804,7 +2804,6 @@ static int qeth_l3_open(struct net_devic
+ 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))
+@@ -2818,7 +2817,6 @@ static int qeth_l3_stop(struct net_devic
+
+ 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;
+@@ -3222,9 +3220,13 @@ static int qeth_l3_recover(void *ptr)
+ if (!rc)
+ dev_info(&card->gdev->dev,
+ "Device successfully recovered!\n");
+- else
++ else {
++ rtnl_lock();
++ dev_close(card->dev);
++ rtnl_unlock();
+ dev_warn(&card->gdev->dev, "The qeth device driver "
+ "failed to recover an error on the device\n");
++ }
+ return 0;
+ }
+