diff options
author | Ursula Braun <ursula.braun@de.ibm.com> | 2010-06-21 18:57:02 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-06-23 16:16:32 -0400 |
commit | 59b60e9724318dd757896742dcd68e516996bbc5 (patch) | |
tree | 28889d729dd5b901a446a4b7e08f9d3fffdb639d /drivers/s390/net | |
parent | 4eaef482df464d1038b75769d43ac06ce0d16cd2 (diff) |
smsgiucv: guarantee single iucv connect in thaw
If another smsgiucv_app device exists, suspend / resume fails with
iucv path list corruption, because the same iucv_path_connect is
called twice.
The patch introduces a flag to save connect status of the smsgiucv
path to make sure iucv_path_connect in smsg_pm_restore_thaw is
called only once.
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>
Diffstat (limited to 'drivers/s390/net')
-rw-r--r-- | drivers/s390/net/smsgiucv.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 70491274da1..65e1cf10494 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -47,6 +47,7 @@ static struct device *smsg_dev; | |||
47 | 47 | ||
48 | static DEFINE_SPINLOCK(smsg_list_lock); | 48 | static DEFINE_SPINLOCK(smsg_list_lock); |
49 | static LIST_HEAD(smsg_list); | 49 | static LIST_HEAD(smsg_list); |
50 | static int iucv_path_connected; | ||
50 | 51 | ||
51 | static int smsg_path_pending(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]); | 52 | static int smsg_path_pending(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]); |
52 | static void smsg_message_pending(struct iucv_path *, struct iucv_message *); | 53 | static void smsg_message_pending(struct iucv_path *, struct iucv_message *); |
@@ -142,8 +143,10 @@ static int smsg_pm_freeze(struct device *dev) | |||
142 | #ifdef CONFIG_PM_DEBUG | 143 | #ifdef CONFIG_PM_DEBUG |
143 | printk(KERN_WARNING "smsg_pm_freeze\n"); | 144 | printk(KERN_WARNING "smsg_pm_freeze\n"); |
144 | #endif | 145 | #endif |
145 | if (smsg_path) | 146 | if (smsg_path && iucv_path_connected) { |
146 | iucv_path_sever(smsg_path, NULL); | 147 | iucv_path_sever(smsg_path, NULL); |
148 | iucv_path_connected = 0; | ||
149 | } | ||
147 | return 0; | 150 | return 0; |
148 | } | 151 | } |
149 | 152 | ||
@@ -154,7 +157,7 @@ static int smsg_pm_restore_thaw(struct device *dev) | |||
154 | #ifdef CONFIG_PM_DEBUG | 157 | #ifdef CONFIG_PM_DEBUG |
155 | printk(KERN_WARNING "smsg_pm_restore_thaw\n"); | 158 | printk(KERN_WARNING "smsg_pm_restore_thaw\n"); |
156 | #endif | 159 | #endif |
157 | if (smsg_path) { | 160 | if (smsg_path && iucv_path_connected) { |
158 | memset(smsg_path, 0, sizeof(*smsg_path)); | 161 | memset(smsg_path, 0, sizeof(*smsg_path)); |
159 | smsg_path->msglim = 255; | 162 | smsg_path->msglim = 255; |
160 | smsg_path->flags = 0; | 163 | smsg_path->flags = 0; |
@@ -165,6 +168,8 @@ static int smsg_pm_restore_thaw(struct device *dev) | |||
165 | printk(KERN_ERR | 168 | printk(KERN_ERR |
166 | "iucv_path_connect returned with rc %i\n", rc); | 169 | "iucv_path_connect returned with rc %i\n", rc); |
167 | #endif | 170 | #endif |
171 | if (!rc) | ||
172 | iucv_path_connected = 1; | ||
168 | cpcmd("SET SMSG IUCV", NULL, 0, NULL); | 173 | cpcmd("SET SMSG IUCV", NULL, 0, NULL); |
169 | } | 174 | } |
170 | return 0; | 175 | return 0; |
@@ -214,6 +219,8 @@ static int __init smsg_init(void) | |||
214 | NULL, NULL, NULL); | 219 | NULL, NULL, NULL); |
215 | if (rc) | 220 | if (rc) |
216 | goto out_free_path; | 221 | goto out_free_path; |
222 | else | ||
223 | iucv_path_connected = 1; | ||
217 | smsg_dev = kzalloc(sizeof(struct device), GFP_KERNEL); | 224 | smsg_dev = kzalloc(sizeof(struct device), GFP_KERNEL); |
218 | if (!smsg_dev) { | 225 | if (!smsg_dev) { |
219 | rc = -ENOMEM; | 226 | rc = -ENOMEM; |