]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: qeth: qeth recovery fails | |
3 | References: bnc#434333 | |
4 | ||
5 | Symptom: Device is not functional after a recovery | |
6 | Problem: The handling of the IFF flags changed in 2.6.27 code | |
7 | Solution: Do not touch IFF_UP flag during qeth recovery, but invoke | |
8 | dev_close() in case of failing recovery. | |
9 | Cancel outstanding control commands in case of Data Checks or | |
10 | Channel Checks. | |
11 | Do not invoke qeth_l2_del_all_mc() in case of a hard stop to speed | |
12 | up removal of qeth devices. | |
13 | ||
14 | Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com> | |
15 | Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> | |
16 | ||
17 | Acked-by: John Jolly <jjolly@suse.de> | |
18 | --- | |
19 | ||
20 | drivers/s390/net/qeth_core_main.c | 4 +++- | |
21 | drivers/s390/net/qeth_l2_main.c | 11 +++++++---- | |
22 | drivers/s390/net/qeth_l3_main.c | 8 +++++--- | |
23 | 3 files changed, 15 insertions(+), 8 deletions(-) | |
24 | ||
25 | Index: linux-sles11/drivers/s390/net/qeth_core_main.c | |
26 | =================================================================== | |
27 | --- linux-sles11.orig/drivers/s390/net/qeth_core_main.c | |
28 | +++ linux-sles11/drivers/s390/net/qeth_core_main.c | |
29 | @@ -767,7 +767,7 @@ static int qeth_get_problem(struct ccw_d | |
30 | if (sense[SENSE_COMMAND_REJECT_BYTE] & | |
31 | SENSE_COMMAND_REJECT_FLAG) { | |
32 | QETH_DBF_TEXT(TRACE, 2, "CMDREJi"); | |
33 | - return 0; | |
34 | + return 1; | |
35 | } | |
36 | if ((sense[2] == 0xaf) && (sense[3] == 0xfe)) { | |
37 | QETH_DBF_TEXT(TRACE, 2, "AFFE"); | |
38 | @@ -895,6 +895,7 @@ static void qeth_irq(struct ccw_device * | |
39 | } | |
40 | rc = qeth_get_problem(cdev, irb); | |
41 | if (rc) { | |
42 | + qeth_clear_ipacmd_list(card); | |
43 | qeth_schedule_recovery(card); | |
44 | goto out; | |
45 | } | |
46 | @@ -4160,6 +4161,7 @@ static void qeth_core_remove_device(stru | |
47 | unsigned long flags; | |
48 | struct qeth_card *card = dev_get_drvdata(&gdev->dev); | |
49 | ||
50 | + QETH_DBF_TEXT(SETUP, 2, "removedv"); | |
51 | if (card->discipline.ccwgdriver) { | |
52 | card->discipline.ccwgdriver->remove(gdev); | |
53 | qeth_core_free_discipline(card); | |
54 | Index: linux-sles11/drivers/s390/net/qeth_l2_main.c | |
55 | =================================================================== | |
56 | --- linux-sles11.orig/drivers/s390/net/qeth_l2_main.c | |
57 | +++ linux-sles11/drivers/s390/net/qeth_l2_main.c | |
58 | @@ -397,7 +397,8 @@ static int qeth_l2_stop_card(struct qeth | |
59 | } | |
60 | if (card->state == CARD_STATE_SOFTSETUP) { | |
61 | qeth_l2_process_vlans(card, 1); | |
62 | - qeth_l2_del_all_mc(card); | |
63 | + if (!card->use_hard_stop) | |
64 | + qeth_l2_del_all_mc(card); | |
65 | qeth_clear_ipacmd_list(card); | |
66 | card->state = CARD_STATE_HARDSETUP; | |
67 | } | |
68 | @@ -829,7 +830,6 @@ static int qeth_l2_open(struct net_devic | |
69 | } | |
70 | card->data.state = CH_STATE_UP; | |
71 | card->state = CARD_STATE_UP; | |
72 | - card->dev->flags |= IFF_UP; | |
73 | netif_start_queue(dev); | |
74 | ||
75 | if (!card->lan_online && netif_carrier_ok(dev)) | |
76 | @@ -844,7 +844,6 @@ static int qeth_l2_stop(struct net_devic | |
77 | ||
78 | QETH_DBF_TEXT(TRACE, 4, "qethstop"); | |
79 | netif_tx_disable(dev); | |
80 | - card->dev->flags &= ~IFF_UP; | |
81 | if (card->state == CARD_STATE_UP) | |
82 | card->state = CARD_STATE_SOFTSETUP; | |
83 | return 0; | |
84 | @@ -1136,9 +1135,13 @@ static int qeth_l2_recover(void *ptr) | |
85 | if (!rc) | |
86 | dev_info(&card->gdev->dev, | |
87 | "Device successfully recovered!\n"); | |
88 | - else | |
89 | + else { | |
90 | + rtnl_lock(); | |
91 | + dev_close(card->dev); | |
92 | + rtnl_unlock(); | |
93 | dev_warn(&card->gdev->dev, "The qeth device driver " | |
94 | "failed to recover an error on the device\n"); | |
95 | + } | |
96 | return 0; | |
97 | } | |
98 | ||
99 | Index: linux-sles11/drivers/s390/net/qeth_l3_main.c | |
100 | =================================================================== | |
101 | --- linux-sles11.orig/drivers/s390/net/qeth_l3_main.c | |
102 | +++ linux-sles11/drivers/s390/net/qeth_l3_main.c | |
103 | @@ -2804,7 +2804,6 @@ static int qeth_l3_open(struct net_devic | |
104 | return -ENODEV; | |
105 | card->data.state = CH_STATE_UP; | |
106 | card->state = CARD_STATE_UP; | |
107 | - card->dev->flags |= IFF_UP; | |
108 | netif_start_queue(dev); | |
109 | ||
110 | if (!card->lan_online && netif_carrier_ok(dev)) | |
111 | @@ -2818,7 +2817,6 @@ static int qeth_l3_stop(struct net_devic | |
112 | ||
113 | QETH_DBF_TEXT(TRACE, 4, "qethstop"); | |
114 | netif_tx_disable(dev); | |
115 | - card->dev->flags &= ~IFF_UP; | |
116 | if (card->state == CARD_STATE_UP) | |
117 | card->state = CARD_STATE_SOFTSETUP; | |
118 | return 0; | |
119 | @@ -3222,9 +3220,13 @@ static int qeth_l3_recover(void *ptr) | |
120 | if (!rc) | |
121 | dev_info(&card->gdev->dev, | |
122 | "Device successfully recovered!\n"); | |
123 | - else | |
124 | + else { | |
125 | + rtnl_lock(); | |
126 | + dev_close(card->dev); | |
127 | + rtnl_unlock(); | |
128 | dev_warn(&card->gdev->dev, "The qeth device driver " | |
129 | "failed to recover an error on the device\n"); | |
130 | + } | |
131 | return 0; | |
132 | } | |
133 |