diff options
author | Frank Blaschka <frank.blaschka@de.ibm.com> | 2010-05-11 15:34:47 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-05-16 03:50:11 -0400 |
commit | c4949f074332a64baeb2ead6ab9319ca37642f96 (patch) | |
tree | 185005280b499114ba872560efe21ec75b0ba726 /drivers/s390 | |
parent | 65a1f898efac136aeea65509e61ac6cdecd4f6bf (diff) |
qeth: synchronize configuration interface
Synchronize access to the drivers configuration interface.
Also do not allow configuration changes during online/offline
transition.
Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/net/qeth_core.h | 1 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_main.c | 1 | ||||
-rw-r--r-- | drivers/s390/net/qeth_core_sys.c | 148 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l2_main.c | 8 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_main.c | 8 | ||||
-rw-r--r-- | drivers/s390/net/qeth_l3_sys.c | 244 |
6 files changed, 242 insertions, 168 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index bab0febf0725..af661cd527df 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h | |||
@@ -740,6 +740,7 @@ struct qeth_card { | |||
740 | atomic_t force_alloc_skb; | 740 | atomic_t force_alloc_skb; |
741 | struct service_level qeth_service_level; | 741 | struct service_level qeth_service_level; |
742 | struct qdio_ssqd_desc ssqd; | 742 | struct qdio_ssqd_desc ssqd; |
743 | struct mutex conf_mutex; | ||
743 | }; | 744 | }; |
744 | 745 | ||
745 | struct qeth_card_list_struct { | 746 | struct qeth_card_list_struct { |
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 52096c9194f0..fd1f48c771fc 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c | |||
@@ -1100,6 +1100,7 @@ static int qeth_setup_card(struct qeth_card *card) | |||
1100 | spin_lock_init(&card->lock); | 1100 | spin_lock_init(&card->lock); |
1101 | spin_lock_init(&card->ip_lock); | 1101 | spin_lock_init(&card->ip_lock); |
1102 | spin_lock_init(&card->thread_mask_lock); | 1102 | spin_lock_init(&card->thread_mask_lock); |
1103 | mutex_init(&card->conf_mutex); | ||
1103 | card->thread_start_mask = 0; | 1104 | card->thread_start_mask = 0; |
1104 | card->thread_allowed_mask = 0; | 1105 | card->thread_allowed_mask = 0; |
1105 | card->thread_running_mask = 0; | 1106 | card->thread_running_mask = 0; |
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c index 25dfd5abd19b..cbac4050afb2 100644 --- a/drivers/s390/net/qeth_core_sys.c +++ b/drivers/s390/net/qeth_core_sys.c | |||
@@ -122,23 +122,32 @@ static ssize_t qeth_dev_portno_store(struct device *dev, | |||
122 | struct qeth_card *card = dev_get_drvdata(dev); | 122 | struct qeth_card *card = dev_get_drvdata(dev); |
123 | char *tmp; | 123 | char *tmp; |
124 | unsigned int portno, limit; | 124 | unsigned int portno, limit; |
125 | int rc = 0; | ||
125 | 126 | ||
126 | if (!card) | 127 | if (!card) |
127 | return -EINVAL; | 128 | return -EINVAL; |
128 | 129 | ||
130 | mutex_lock(&card->conf_mutex); | ||
129 | if ((card->state != CARD_STATE_DOWN) && | 131 | if ((card->state != CARD_STATE_DOWN) && |
130 | (card->state != CARD_STATE_RECOVER)) | 132 | (card->state != CARD_STATE_RECOVER)) { |
131 | return -EPERM; | 133 | rc = -EPERM; |
134 | goto out; | ||
135 | } | ||
132 | 136 | ||
133 | portno = simple_strtoul(buf, &tmp, 16); | 137 | portno = simple_strtoul(buf, &tmp, 16); |
134 | if (portno > QETH_MAX_PORTNO) | 138 | if (portno > QETH_MAX_PORTNO) { |
135 | return -EINVAL; | 139 | rc = -EINVAL; |
140 | goto out; | ||
141 | } | ||
136 | limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt); | 142 | limit = (card->ssqd.pcnt ? card->ssqd.pcnt - 1 : card->ssqd.pcnt); |
137 | if (portno > limit) | 143 | if (portno > limit) { |
138 | return -EINVAL; | 144 | rc = -EINVAL; |
139 | 145 | goto out; | |
146 | } | ||
140 | card->info.portno = portno; | 147 | card->info.portno = portno; |
141 | return count; | 148 | out: |
149 | mutex_unlock(&card->conf_mutex); | ||
150 | return rc ? rc : count; | ||
142 | } | 151 | } |
143 | 152 | ||
144 | static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store); | 153 | static DEVICE_ATTR(portno, 0644, qeth_dev_portno_show, qeth_dev_portno_store); |
@@ -165,18 +174,23 @@ static ssize_t qeth_dev_portname_store(struct device *dev, | |||
165 | { | 174 | { |
166 | struct qeth_card *card = dev_get_drvdata(dev); | 175 | struct qeth_card *card = dev_get_drvdata(dev); |
167 | char *tmp; | 176 | char *tmp; |
168 | int i; | 177 | int i, rc = 0; |
169 | 178 | ||
170 | if (!card) | 179 | if (!card) |
171 | return -EINVAL; | 180 | return -EINVAL; |
172 | 181 | ||
182 | mutex_lock(&card->conf_mutex); | ||
173 | if ((card->state != CARD_STATE_DOWN) && | 183 | if ((card->state != CARD_STATE_DOWN) && |
174 | (card->state != CARD_STATE_RECOVER)) | 184 | (card->state != CARD_STATE_RECOVER)) { |
175 | return -EPERM; | 185 | rc = -EPERM; |
186 | goto out; | ||
187 | } | ||
176 | 188 | ||
177 | tmp = strsep((char **) &buf, "\n"); | 189 | tmp = strsep((char **) &buf, "\n"); |
178 | if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) | 190 | if ((strlen(tmp) > 8) || (strlen(tmp) == 0)) { |
179 | return -EINVAL; | 191 | rc = -EINVAL; |
192 | goto out; | ||
193 | } | ||
180 | 194 | ||
181 | card->info.portname[0] = strlen(tmp); | 195 | card->info.portname[0] = strlen(tmp); |
182 | /* for beauty reasons */ | 196 | /* for beauty reasons */ |
@@ -184,8 +198,9 @@ static ssize_t qeth_dev_portname_store(struct device *dev, | |||
184 | card->info.portname[i] = ' '; | 198 | card->info.portname[i] = ' '; |
185 | strcpy(card->info.portname + 1, tmp); | 199 | strcpy(card->info.portname + 1, tmp); |
186 | ASCEBC(card->info.portname + 1, 8); | 200 | ASCEBC(card->info.portname + 1, 8); |
187 | 201 | out: | |
188 | return count; | 202 | mutex_unlock(&card->conf_mutex); |
203 | return rc ? rc : count; | ||
189 | } | 204 | } |
190 | 205 | ||
191 | static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show, | 206 | static DEVICE_ATTR(portname, 0644, qeth_dev_portname_show, |
@@ -215,20 +230,25 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev, | |||
215 | { | 230 | { |
216 | struct qeth_card *card = dev_get_drvdata(dev); | 231 | struct qeth_card *card = dev_get_drvdata(dev); |
217 | char *tmp; | 232 | char *tmp; |
233 | int rc = 0; | ||
218 | 234 | ||
219 | if (!card) | 235 | if (!card) |
220 | return -EINVAL; | 236 | return -EINVAL; |
221 | 237 | ||
238 | mutex_lock(&card->conf_mutex); | ||
222 | if ((card->state != CARD_STATE_DOWN) && | 239 | if ((card->state != CARD_STATE_DOWN) && |
223 | (card->state != CARD_STATE_RECOVER)) | 240 | (card->state != CARD_STATE_RECOVER)) { |
224 | return -EPERM; | 241 | rc = -EPERM; |
242 | goto out; | ||
243 | } | ||
225 | 244 | ||
226 | /* check if 1920 devices are supported , | 245 | /* check if 1920 devices are supported , |
227 | * if though we have to permit priority queueing | 246 | * if though we have to permit priority queueing |
228 | */ | 247 | */ |
229 | if (card->qdio.no_out_queues == 1) { | 248 | if (card->qdio.no_out_queues == 1) { |
230 | card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; | 249 | card->qdio.do_prio_queueing = QETH_PRIOQ_DEFAULT; |
231 | return -EPERM; | 250 | rc = -EPERM; |
251 | goto out; | ||
232 | } | 252 | } |
233 | 253 | ||
234 | tmp = strsep((char **) &buf, "\n"); | 254 | tmp = strsep((char **) &buf, "\n"); |
@@ -251,10 +271,11 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev, | |||
251 | } else if (!strcmp(tmp, "no_prio_queueing")) { | 271 | } else if (!strcmp(tmp, "no_prio_queueing")) { |
252 | card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; | 272 | card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING; |
253 | card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; | 273 | card->qdio.default_out_queue = QETH_DEFAULT_QUEUE; |
254 | } else { | 274 | } else |
255 | return -EINVAL; | 275 | rc = -EINVAL; |
256 | } | 276 | out: |
257 | return count; | 277 | mutex_unlock(&card->conf_mutex); |
278 | return rc ? rc : count; | ||
258 | } | 279 | } |
259 | 280 | ||
260 | static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show, | 281 | static DEVICE_ATTR(priority_queueing, 0644, qeth_dev_prioqing_show, |
@@ -277,14 +298,17 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev, | |||
277 | struct qeth_card *card = dev_get_drvdata(dev); | 298 | struct qeth_card *card = dev_get_drvdata(dev); |
278 | char *tmp; | 299 | char *tmp; |
279 | int cnt, old_cnt; | 300 | int cnt, old_cnt; |
280 | int rc; | 301 | int rc = 0; |
281 | 302 | ||
282 | if (!card) | 303 | if (!card) |
283 | return -EINVAL; | 304 | return -EINVAL; |
284 | 305 | ||
306 | mutex_lock(&card->conf_mutex); | ||
285 | if ((card->state != CARD_STATE_DOWN) && | 307 | if ((card->state != CARD_STATE_DOWN) && |
286 | (card->state != CARD_STATE_RECOVER)) | 308 | (card->state != CARD_STATE_RECOVER)) { |
287 | return -EPERM; | 309 | rc = -EPERM; |
310 | goto out; | ||
311 | } | ||
288 | 312 | ||
289 | old_cnt = card->qdio.in_buf_pool.buf_count; | 313 | old_cnt = card->qdio.in_buf_pool.buf_count; |
290 | cnt = simple_strtoul(buf, &tmp, 10); | 314 | cnt = simple_strtoul(buf, &tmp, 10); |
@@ -293,7 +317,9 @@ static ssize_t qeth_dev_bufcnt_store(struct device *dev, | |||
293 | if (old_cnt != cnt) { | 317 | if (old_cnt != cnt) { |
294 | rc = qeth_realloc_buffer_pool(card, cnt); | 318 | rc = qeth_realloc_buffer_pool(card, cnt); |
295 | } | 319 | } |
296 | return count; | 320 | out: |
321 | mutex_unlock(&card->conf_mutex); | ||
322 | return rc ? rc : count; | ||
297 | } | 323 | } |
298 | 324 | ||
299 | static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show, | 325 | static DEVICE_ATTR(buffer_count, 0644, qeth_dev_bufcnt_show, |
@@ -337,25 +363,27 @@ static ssize_t qeth_dev_performance_stats_store(struct device *dev, | |||
337 | { | 363 | { |
338 | struct qeth_card *card = dev_get_drvdata(dev); | 364 | struct qeth_card *card = dev_get_drvdata(dev); |
339 | char *tmp; | 365 | char *tmp; |
340 | int i; | 366 | int i, rc = 0; |
341 | 367 | ||
342 | if (!card) | 368 | if (!card) |
343 | return -EINVAL; | 369 | return -EINVAL; |
344 | 370 | ||
371 | mutex_lock(&card->conf_mutex); | ||
345 | i = simple_strtoul(buf, &tmp, 16); | 372 | i = simple_strtoul(buf, &tmp, 16); |
346 | if ((i == 0) || (i == 1)) { | 373 | if ((i == 0) || (i == 1)) { |
347 | if (i == card->options.performance_stats) | 374 | if (i == card->options.performance_stats) |
348 | return count; | 375 | goto out;; |
349 | card->options.performance_stats = i; | 376 | card->options.performance_stats = i; |
350 | if (i == 0) | 377 | if (i == 0) |
351 | memset(&card->perf_stats, 0, | 378 | memset(&card->perf_stats, 0, |
352 | sizeof(struct qeth_perf_stats)); | 379 | sizeof(struct qeth_perf_stats)); |
353 | card->perf_stats.initial_rx_packets = card->stats.rx_packets; | 380 | card->perf_stats.initial_rx_packets = card->stats.rx_packets; |
354 | card->perf_stats.initial_tx_packets = card->stats.tx_packets; | 381 | card->perf_stats.initial_tx_packets = card->stats.tx_packets; |
355 | } else { | 382 | } else |
356 | return -EINVAL; | 383 | rc = -EINVAL; |
357 | } | 384 | out: |
358 | return count; | 385 | mutex_unlock(&card->conf_mutex); |
386 | return rc ? rc : count; | ||
359 | } | 387 | } |
360 | 388 | ||
361 | static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show, | 389 | static DEVICE_ATTR(performance_stats, 0644, qeth_dev_performance_stats_show, |
@@ -377,15 +405,17 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
377 | { | 405 | { |
378 | struct qeth_card *card = dev_get_drvdata(dev); | 406 | struct qeth_card *card = dev_get_drvdata(dev); |
379 | char *tmp; | 407 | char *tmp; |
380 | int i, rc; | 408 | int i, rc = 0; |
381 | enum qeth_discipline_id newdis; | 409 | enum qeth_discipline_id newdis; |
382 | 410 | ||
383 | if (!card) | 411 | if (!card) |
384 | return -EINVAL; | 412 | return -EINVAL; |
385 | 413 | ||
386 | if (((card->state != CARD_STATE_DOWN) && | 414 | mutex_lock(&card->conf_mutex); |
387 | (card->state != CARD_STATE_RECOVER))) | 415 | if (card->state != CARD_STATE_DOWN) { |
388 | return -EPERM; | 416 | rc = -EPERM; |
417 | goto out; | ||
418 | } | ||
389 | 419 | ||
390 | i = simple_strtoul(buf, &tmp, 16); | 420 | i = simple_strtoul(buf, &tmp, 16); |
391 | switch (i) { | 421 | switch (i) { |
@@ -396,12 +426,13 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
396 | newdis = QETH_DISCIPLINE_LAYER2; | 426 | newdis = QETH_DISCIPLINE_LAYER2; |
397 | break; | 427 | break; |
398 | default: | 428 | default: |
399 | return -EINVAL; | 429 | rc = -EINVAL; |
430 | goto out; | ||
400 | } | 431 | } |
401 | 432 | ||
402 | if (card->options.layer2 == newdis) { | 433 | if (card->options.layer2 == newdis) |
403 | return count; | 434 | goto out; |
404 | } else { | 435 | else { |
405 | if (card->discipline.ccwgdriver) { | 436 | if (card->discipline.ccwgdriver) { |
406 | card->discipline.ccwgdriver->remove(card->gdev); | 437 | card->discipline.ccwgdriver->remove(card->gdev); |
407 | qeth_core_free_discipline(card); | 438 | qeth_core_free_discipline(card); |
@@ -410,12 +441,12 @@ static ssize_t qeth_dev_layer2_store(struct device *dev, | |||
410 | 441 | ||
411 | rc = qeth_core_load_discipline(card, newdis); | 442 | rc = qeth_core_load_discipline(card, newdis); |
412 | if (rc) | 443 | if (rc) |
413 | return rc; | 444 | goto out; |
414 | 445 | ||
415 | rc = card->discipline.ccwgdriver->probe(card->gdev); | 446 | rc = card->discipline.ccwgdriver->probe(card->gdev); |
416 | if (rc) | 447 | out: |
417 | return rc; | 448 | mutex_unlock(&card->conf_mutex); |
418 | return count; | 449 | return rc ? rc : count; |
419 | } | 450 | } |
420 | 451 | ||
421 | static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show, | 452 | static DEVICE_ATTR(layer2, 0644, qeth_dev_layer2_show, |
@@ -454,11 +485,10 @@ static ssize_t qeth_dev_isolation_store(struct device *dev, | |||
454 | char *tmp, *curtoken; | 485 | char *tmp, *curtoken; |
455 | curtoken = (char *) buf; | 486 | curtoken = (char *) buf; |
456 | 487 | ||
457 | if (!card) { | 488 | if (!card) |
458 | rc = -EINVAL; | 489 | return -EINVAL; |
459 | goto out; | ||
460 | } | ||
461 | 490 | ||
491 | mutex_lock(&card->conf_mutex); | ||
462 | /* check for unknown, too, in case we do not yet know who we are */ | 492 | /* check for unknown, too, in case we do not yet know who we are */ |
463 | if (card->info.type != QETH_CARD_TYPE_OSAE && | 493 | if (card->info.type != QETH_CARD_TYPE_OSAE && |
464 | card->info.type != QETH_CARD_TYPE_UNKNOWN) { | 494 | card->info.type != QETH_CARD_TYPE_UNKNOWN) { |
@@ -491,6 +521,7 @@ static ssize_t qeth_dev_isolation_store(struct device *dev, | |||
491 | rc = ipa_rc; | 521 | rc = ipa_rc; |
492 | } | 522 | } |
493 | out: | 523 | out: |
524 | mutex_unlock(&card->conf_mutex); | ||
494 | return rc; | 525 | return rc; |
495 | } | 526 | } |
496 | 527 | ||
@@ -510,22 +541,25 @@ static ssize_t qeth_dev_blkt_store(struct qeth_card *card, | |||
510 | const char *buf, size_t count, int *value, int max_value) | 541 | const char *buf, size_t count, int *value, int max_value) |
511 | { | 542 | { |
512 | char *tmp; | 543 | char *tmp; |
513 | int i; | 544 | int i, rc = 0; |
514 | 545 | ||
515 | if (!card) | 546 | if (!card) |
516 | return -EINVAL; | 547 | return -EINVAL; |
517 | 548 | ||
549 | mutex_lock(&card->conf_mutex); | ||
518 | if ((card->state != CARD_STATE_DOWN) && | 550 | if ((card->state != CARD_STATE_DOWN) && |
519 | (card->state != CARD_STATE_RECOVER)) | 551 | (card->state != CARD_STATE_RECOVER)) { |
520 | return -EPERM; | 552 | rc = -EPERM; |
521 | 553 | goto out; | |
554 | } | ||
522 | i = simple_strtoul(buf, &tmp, 10); | 555 | i = simple_strtoul(buf, &tmp, 10); |
523 | if (i <= max_value) { | 556 | if (i <= max_value) |
524 | *value = i; | 557 | *value = i; |
525 | } else { | 558 | else |
526 | return -EINVAL; | 559 | rc = -EINVAL; |
527 | } | 560 | out: |
528 | return count; | 561 | mutex_unlock(&card->conf_mutex); |
562 | return rc ? rc : count; | ||
529 | } | 563 | } |
530 | 564 | ||
531 | static ssize_t qeth_dev_blkt_total_show(struct device *dev, | 565 | static ssize_t qeth_dev_blkt_total_show(struct device *dev, |
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 904b1f3567b4..b447e1998c6b 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c | |||
@@ -924,6 +924,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
924 | enum qeth_card_states recover_flag; | 924 | enum qeth_card_states recover_flag; |
925 | 925 | ||
926 | BUG_ON(!card); | 926 | BUG_ON(!card); |
927 | mutex_lock(&card->conf_mutex); | ||
927 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); | 928 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); |
928 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); | 929 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); |
929 | 930 | ||
@@ -956,7 +957,7 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
956 | dev_warn(&card->gdev->dev, | 957 | dev_warn(&card->gdev->dev, |
957 | "The LAN is offline\n"); | 958 | "The LAN is offline\n"); |
958 | card->lan_online = 0; | 959 | card->lan_online = 0; |
959 | return 0; | 960 | goto out; |
960 | } | 961 | } |
961 | rc = -ENODEV; | 962 | rc = -ENODEV; |
962 | goto out_remove; | 963 | goto out_remove; |
@@ -995,6 +996,8 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
995 | } | 996 | } |
996 | /* let user_space know that device is online */ | 997 | /* let user_space know that device is online */ |
997 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); | 998 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); |
999 | out: | ||
1000 | mutex_unlock(&card->conf_mutex); | ||
998 | return 0; | 1001 | return 0; |
999 | 1002 | ||
1000 | out_remove: | 1003 | out_remove: |
@@ -1007,6 +1010,7 @@ out_remove: | |||
1007 | card->state = CARD_STATE_RECOVER; | 1010 | card->state = CARD_STATE_RECOVER; |
1008 | else | 1011 | else |
1009 | card->state = CARD_STATE_DOWN; | 1012 | card->state = CARD_STATE_DOWN; |
1013 | mutex_unlock(&card->conf_mutex); | ||
1010 | return rc; | 1014 | return rc; |
1011 | } | 1015 | } |
1012 | 1016 | ||
@@ -1022,6 +1026,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, | |||
1022 | int rc = 0, rc2 = 0, rc3 = 0; | 1026 | int rc = 0, rc2 = 0, rc3 = 0; |
1023 | enum qeth_card_states recover_flag; | 1027 | enum qeth_card_states recover_flag; |
1024 | 1028 | ||
1029 | mutex_lock(&card->conf_mutex); | ||
1025 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); | 1030 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); |
1026 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); | 1031 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); |
1027 | 1032 | ||
@@ -1040,6 +1045,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev, | |||
1040 | card->state = CARD_STATE_RECOVER; | 1045 | card->state = CARD_STATE_RECOVER; |
1041 | /* let user_space know that device is offline */ | 1046 | /* let user_space know that device is offline */ |
1042 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); | 1047 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); |
1048 | mutex_unlock(&card->conf_mutex); | ||
1043 | return 0; | 1049 | return 0; |
1044 | } | 1050 | } |
1045 | 1051 | ||
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 8bcad24ccf37..83c7f9444c4f 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c | |||
@@ -3378,6 +3378,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3378 | enum qeth_card_states recover_flag; | 3378 | enum qeth_card_states recover_flag; |
3379 | 3379 | ||
3380 | BUG_ON(!card); | 3380 | BUG_ON(!card); |
3381 | mutex_lock(&card->conf_mutex); | ||
3381 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); | 3382 | QETH_DBF_TEXT(SETUP, 2, "setonlin"); |
3382 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); | 3383 | QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *)); |
3383 | 3384 | ||
@@ -3409,7 +3410,7 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3409 | dev_warn(&card->gdev->dev, | 3410 | dev_warn(&card->gdev->dev, |
3410 | "The LAN is offline\n"); | 3411 | "The LAN is offline\n"); |
3411 | card->lan_online = 0; | 3412 | card->lan_online = 0; |
3412 | return 0; | 3413 | goto out; |
3413 | } | 3414 | } |
3414 | rc = -ENODEV; | 3415 | rc = -ENODEV; |
3415 | goto out_remove; | 3416 | goto out_remove; |
@@ -3456,6 +3457,8 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) | |||
3456 | } | 3457 | } |
3457 | /* let user_space know that device is online */ | 3458 | /* let user_space know that device is online */ |
3458 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); | 3459 | kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); |
3460 | out: | ||
3461 | mutex_unlock(&card->conf_mutex); | ||
3459 | return 0; | 3462 | return 0; |
3460 | out_remove: | 3463 | out_remove: |
3461 | card->use_hard_stop = 1; | 3464 | card->use_hard_stop = 1; |
@@ -3467,6 +3470,7 @@ out_remove: | |||
3467 | card->state = CARD_STATE_RECOVER; | 3470 | card->state = CARD_STATE_RECOVER; |
3468 | else | 3471 | else |
3469 | card->state = CARD_STATE_DOWN; | 3472 | card->state = CARD_STATE_DOWN; |
3473 | mutex_unlock(&card->conf_mutex); | ||
3470 | return rc; | 3474 | return rc; |
3471 | } | 3475 | } |
3472 | 3476 | ||
@@ -3482,6 +3486,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, | |||
3482 | int rc = 0, rc2 = 0, rc3 = 0; | 3486 | int rc = 0, rc2 = 0, rc3 = 0; |
3483 | enum qeth_card_states recover_flag; | 3487 | enum qeth_card_states recover_flag; |
3484 | 3488 | ||
3489 | mutex_lock(&card->conf_mutex); | ||
3485 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); | 3490 | QETH_DBF_TEXT(SETUP, 3, "setoffl"); |
3486 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); | 3491 | QETH_DBF_HEX(SETUP, 3, &card, sizeof(void *)); |
3487 | 3492 | ||
@@ -3500,6 +3505,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev, | |||
3500 | card->state = CARD_STATE_RECOVER; | 3505 | card->state = CARD_STATE_RECOVER; |
3501 | /* let user_space know that device is offline */ | 3506 | /* let user_space know that device is offline */ |
3502 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); | 3507 | kobject_uevent(&cgdev->dev.kobj, KOBJ_CHANGE); |
3508 | mutex_unlock(&card->conf_mutex); | ||
3503 | return 0; | 3509 | return 0; |
3504 | } | 3510 | } |
3505 | 3511 | ||
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index 25b3e7aae44f..fb5318b30e99 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c | |||
@@ -70,10 +70,10 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card, | |||
70 | { | 70 | { |
71 | enum qeth_routing_types old_route_type = route->type; | 71 | enum qeth_routing_types old_route_type = route->type; |
72 | char *tmp; | 72 | char *tmp; |
73 | int rc; | 73 | int rc = 0; |
74 | 74 | ||
75 | tmp = strsep((char **) &buf, "\n"); | 75 | tmp = strsep((char **) &buf, "\n"); |
76 | 76 | mutex_lock(&card->conf_mutex); | |
77 | if (!strcmp(tmp, "no_router")) { | 77 | if (!strcmp(tmp, "no_router")) { |
78 | route->type = NO_ROUTER; | 78 | route->type = NO_ROUTER; |
79 | } else if (!strcmp(tmp, "primary_connector")) { | 79 | } else if (!strcmp(tmp, "primary_connector")) { |
@@ -87,7 +87,8 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card, | |||
87 | } else if (!strcmp(tmp, "multicast_router")) { | 87 | } else if (!strcmp(tmp, "multicast_router")) { |
88 | route->type = MULTICAST_ROUTER; | 88 | route->type = MULTICAST_ROUTER; |
89 | } else { | 89 | } else { |
90 | return -EINVAL; | 90 | rc = -EINVAL; |
91 | goto out; | ||
91 | } | 92 | } |
92 | if (((card->state == CARD_STATE_SOFTSETUP) || | 93 | if (((card->state == CARD_STATE_SOFTSETUP) || |
93 | (card->state == CARD_STATE_UP)) && | 94 | (card->state == CARD_STATE_UP)) && |
@@ -97,7 +98,9 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card, | |||
97 | else if (prot == QETH_PROT_IPV6) | 98 | else if (prot == QETH_PROT_IPV6) |
98 | rc = qeth_l3_setrouting_v6(card); | 99 | rc = qeth_l3_setrouting_v6(card); |
99 | } | 100 | } |
100 | return count; | 101 | out: |
102 | mutex_unlock(&card->conf_mutex); | ||
103 | return rc ? rc : count; | ||
101 | } | 104 | } |
102 | 105 | ||
103 | static ssize_t qeth_l3_dev_route4_store(struct device *dev, | 106 | static ssize_t qeth_l3_dev_route4_store(struct device *dev, |
@@ -157,22 +160,26 @@ static ssize_t qeth_l3_dev_fake_broadcast_store(struct device *dev, | |||
157 | { | 160 | { |
158 | struct qeth_card *card = dev_get_drvdata(dev); | 161 | struct qeth_card *card = dev_get_drvdata(dev); |
159 | char *tmp; | 162 | char *tmp; |
160 | int i; | 163 | int i, rc = 0; |
161 | 164 | ||
162 | if (!card) | 165 | if (!card) |
163 | return -EINVAL; | 166 | return -EINVAL; |
164 | 167 | ||
168 | mutex_lock(&card->conf_mutex); | ||
165 | if ((card->state != CARD_STATE_DOWN) && | 169 | if ((card->state != CARD_STATE_DOWN) && |
166 | (card->state != CARD_STATE_RECOVER)) | 170 | (card->state != CARD_STATE_RECOVER)) { |
167 | return -EPERM; | 171 | rc = -EPERM; |
172 | goto out; | ||
173 | } | ||
168 | 174 | ||
169 | i = simple_strtoul(buf, &tmp, 16); | 175 | i = simple_strtoul(buf, &tmp, 16); |
170 | if ((i == 0) || (i == 1)) | 176 | if ((i == 0) || (i == 1)) |
171 | card->options.fake_broadcast = i; | 177 | card->options.fake_broadcast = i; |
172 | else { | 178 | else |
173 | return -EINVAL; | 179 | rc = -EINVAL; |
174 | } | 180 | out: |
175 | return count; | 181 | mutex_unlock(&card->conf_mutex); |
182 | return rc ? rc : count; | ||
176 | } | 183 | } |
177 | 184 | ||
178 | static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show, | 185 | static DEVICE_ATTR(fake_broadcast, 0644, qeth_l3_dev_fake_broadcast_show, |
@@ -200,31 +207,35 @@ static ssize_t qeth_l3_dev_broadcast_mode_store(struct device *dev, | |||
200 | { | 207 | { |
201 | struct qeth_card *card = dev_get_drvdata(dev); | 208 | struct qeth_card *card = dev_get_drvdata(dev); |
202 | char *tmp; | 209 | char *tmp; |
210 | int rc = 0; | ||
203 | 211 | ||
204 | if (!card) | 212 | if (!card) |
205 | return -EINVAL; | 213 | return -EINVAL; |
206 | 214 | ||
215 | mutex_lock(&card->conf_mutex); | ||
207 | if ((card->state != CARD_STATE_DOWN) && | 216 | if ((card->state != CARD_STATE_DOWN) && |
208 | (card->state != CARD_STATE_RECOVER)) | 217 | (card->state != CARD_STATE_RECOVER)) { |
209 | return -EPERM; | 218 | rc = -EPERM; |
219 | goto out; | ||
220 | } | ||
210 | 221 | ||
211 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || | 222 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || |
212 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { | 223 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { |
213 | return -EINVAL; | 224 | rc = -EINVAL; |
225 | goto out; | ||
214 | } | 226 | } |
215 | 227 | ||
216 | tmp = strsep((char **) &buf, "\n"); | 228 | tmp = strsep((char **) &buf, "\n"); |
217 | 229 | ||
218 | if (!strcmp(tmp, "local")) { | 230 | if (!strcmp(tmp, "local")) |
219 | card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL; | 231 | card->options.broadcast_mode = QETH_TR_BROADCAST_LOCAL; |
220 | return count; | 232 | else if (!strcmp(tmp, "all_rings")) |
221 | } else if (!strcmp(tmp, "all_rings")) { | ||
222 | card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; | 233 | card->options.broadcast_mode = QETH_TR_BROADCAST_ALLRINGS; |
223 | return count; | 234 | else |
224 | } else { | 235 | rc = -EINVAL; |
225 | return -EINVAL; | 236 | out: |
226 | } | 237 | mutex_unlock(&card->conf_mutex); |
227 | return count; | 238 | return rc ? rc : count; |
228 | } | 239 | } |
229 | 240 | ||
230 | static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show, | 241 | static DEVICE_ATTR(broadcast_mode, 0644, qeth_l3_dev_broadcast_mode_show, |
@@ -251,18 +262,22 @@ static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, | |||
251 | { | 262 | { |
252 | struct qeth_card *card = dev_get_drvdata(dev); | 263 | struct qeth_card *card = dev_get_drvdata(dev); |
253 | char *tmp; | 264 | char *tmp; |
254 | int i; | 265 | int i, rc = 0; |
255 | 266 | ||
256 | if (!card) | 267 | if (!card) |
257 | return -EINVAL; | 268 | return -EINVAL; |
258 | 269 | ||
270 | mutex_lock(&card->conf_mutex); | ||
259 | if ((card->state != CARD_STATE_DOWN) && | 271 | if ((card->state != CARD_STATE_DOWN) && |
260 | (card->state != CARD_STATE_RECOVER)) | 272 | (card->state != CARD_STATE_RECOVER)) { |
261 | return -EPERM; | 273 | rc = -EPERM; |
274 | goto out; | ||
275 | } | ||
262 | 276 | ||
263 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || | 277 | if (!((card->info.link_type == QETH_LINK_TYPE_HSTR) || |
264 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { | 278 | (card->info.link_type == QETH_LINK_TYPE_LANE_TR))) { |
265 | return -EINVAL; | 279 | rc = -EINVAL; |
280 | goto out; | ||
266 | } | 281 | } |
267 | 282 | ||
268 | i = simple_strtoul(buf, &tmp, 16); | 283 | i = simple_strtoul(buf, &tmp, 16); |
@@ -270,10 +285,11 @@ static ssize_t qeth_l3_dev_canonical_macaddr_store(struct device *dev, | |||
270 | card->options.macaddr_mode = i? | 285 | card->options.macaddr_mode = i? |
271 | QETH_TR_MACADDR_CANONICAL : | 286 | QETH_TR_MACADDR_CANONICAL : |
272 | QETH_TR_MACADDR_NONCANONICAL; | 287 | QETH_TR_MACADDR_NONCANONICAL; |
273 | else { | 288 | else |
274 | return -EINVAL; | 289 | rc = -EINVAL; |
275 | } | 290 | out: |
276 | return count; | 291 | mutex_unlock(&card->conf_mutex); |
292 | return rc ? rc : count; | ||
277 | } | 293 | } |
278 | 294 | ||
279 | static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show, | 295 | static DEVICE_ATTR(canonical_macaddr, 0644, qeth_l3_dev_canonical_macaddr_show, |
@@ -297,11 +313,12 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev, | |||
297 | struct qeth_card *card = dev_get_drvdata(dev); | 313 | struct qeth_card *card = dev_get_drvdata(dev); |
298 | enum qeth_checksum_types csum_type; | 314 | enum qeth_checksum_types csum_type; |
299 | char *tmp; | 315 | char *tmp; |
300 | int rc; | 316 | int rc = 0; |
301 | 317 | ||
302 | if (!card) | 318 | if (!card) |
303 | return -EINVAL; | 319 | return -EINVAL; |
304 | 320 | ||
321 | mutex_lock(&card->conf_mutex); | ||
305 | tmp = strsep((char **) &buf, "\n"); | 322 | tmp = strsep((char **) &buf, "\n"); |
306 | if (!strcmp(tmp, "sw_checksumming")) | 323 | if (!strcmp(tmp, "sw_checksumming")) |
307 | csum_type = SW_CHECKSUMMING; | 324 | csum_type = SW_CHECKSUMMING; |
@@ -309,13 +326,15 @@ static ssize_t qeth_l3_dev_checksum_store(struct device *dev, | |||
309 | csum_type = HW_CHECKSUMMING; | 326 | csum_type = HW_CHECKSUMMING; |
310 | else if (!strcmp(tmp, "no_checksumming")) | 327 | else if (!strcmp(tmp, "no_checksumming")) |
311 | csum_type = NO_CHECKSUMMING; | 328 | csum_type = NO_CHECKSUMMING; |
312 | else | 329 | else { |
313 | return -EINVAL; | 330 | rc = -EINVAL; |
331 | goto out; | ||
332 | } | ||
314 | 333 | ||
315 | rc = qeth_l3_set_rx_csum(card, csum_type); | 334 | rc = qeth_l3_set_rx_csum(card, csum_type); |
316 | if (rc) | 335 | out: |
317 | return rc; | 336 | mutex_unlock(&card->conf_mutex); |
318 | return count; | 337 | return rc ? rc : count; |
319 | } | 338 | } |
320 | 339 | ||
321 | static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show, | 340 | static DEVICE_ATTR(checksumming, 0644, qeth_l3_dev_checksum_show, |
@@ -336,7 +355,7 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev, | |||
336 | struct device_attribute *attr, const char *buf, size_t count) | 355 | struct device_attribute *attr, const char *buf, size_t count) |
337 | { | 356 | { |
338 | struct qeth_card *card = dev_get_drvdata(dev); | 357 | struct qeth_card *card = dev_get_drvdata(dev); |
339 | int ret; | 358 | int rc = 0; |
340 | unsigned long i; | 359 | unsigned long i; |
341 | 360 | ||
342 | if (!card) | 361 | if (!card) |
@@ -345,19 +364,24 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev, | |||
345 | if (card->info.type != QETH_CARD_TYPE_IQD) | 364 | if (card->info.type != QETH_CARD_TYPE_IQD) |
346 | return -EPERM; | 365 | return -EPERM; |
347 | 366 | ||
367 | mutex_lock(&card->conf_mutex); | ||
348 | if ((card->state != CARD_STATE_DOWN) && | 368 | if ((card->state != CARD_STATE_DOWN) && |
349 | (card->state != CARD_STATE_RECOVER)) | 369 | (card->state != CARD_STATE_RECOVER)) { |
350 | return -EPERM; | 370 | rc = -EPERM; |
371 | goto out; | ||
372 | } | ||
351 | 373 | ||
352 | ret = strict_strtoul(buf, 16, &i); | 374 | rc = strict_strtoul(buf, 16, &i); |
353 | if (ret) | 375 | if (rc) { |
354 | return -EINVAL; | 376 | rc = -EINVAL; |
377 | goto out; | ||
378 | } | ||
355 | switch (i) { | 379 | switch (i) { |
356 | case 0: | 380 | case 0: |
357 | card->options.sniffer = i; | 381 | card->options.sniffer = i; |
358 | break; | 382 | break; |
359 | case 1: | 383 | case 1: |
360 | ret = qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd); | 384 | qdio_get_ssqd_desc(CARD_DDEV(card), &card->ssqd); |
361 | if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) { | 385 | if (card->ssqd.qdioac2 & QETH_SNIFF_AVAIL) { |
362 | card->options.sniffer = i; | 386 | card->options.sniffer = i; |
363 | if (card->qdio.init_pool.buf_count != | 387 | if (card->qdio.init_pool.buf_count != |
@@ -366,11 +390,13 @@ static ssize_t qeth_l3_dev_sniffer_store(struct device *dev, | |||
366 | QETH_IN_BUF_COUNT_MAX); | 390 | QETH_IN_BUF_COUNT_MAX); |
367 | break; | 391 | break; |
368 | } else | 392 | } else |
369 | return -EPERM; | 393 | rc = -EPERM; |
370 | default: /* fall through */ | 394 | default: /* fall through */ |
371 | return -EINVAL; | 395 | rc = -EINVAL; |
372 | } | 396 | } |
373 | return count; | 397 | out: |
398 | mutex_unlock(&card->conf_mutex); | ||
399 | return rc ? rc : count; | ||
374 | } | 400 | } |
375 | 401 | ||
376 | static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show, | 402 | static DEVICE_ATTR(sniffer, 0644, qeth_l3_dev_sniffer_show, |
@@ -412,12 +438,11 @@ static ssize_t qeth_l3_dev_large_send_store(struct device *dev, | |||
412 | else | 438 | else |
413 | return -EINVAL; | 439 | return -EINVAL; |
414 | 440 | ||
415 | if (card->options.large_send == type) | 441 | mutex_lock(&card->conf_mutex); |
416 | return count; | 442 | if (card->options.large_send != type) |
417 | rc = qeth_l3_set_large_send(card, type); | 443 | rc = qeth_l3_set_large_send(card, type); |
418 | if (rc) | 444 | mutex_unlock(&card->conf_mutex); |
419 | return rc; | 445 | return rc ? rc : count; |
420 | return count; | ||
421 | } | 446 | } |
422 | 447 | ||
423 | static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show, | 448 | static DEVICE_ATTR(large_send, 0644, qeth_l3_dev_large_send_show, |
@@ -455,13 +480,17 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, | |||
455 | { | 480 | { |
456 | struct qeth_card *card = dev_get_drvdata(dev); | 481 | struct qeth_card *card = dev_get_drvdata(dev); |
457 | char *tmp; | 482 | char *tmp; |
483 | int rc = 0; | ||
458 | 484 | ||
459 | if (!card) | 485 | if (!card) |
460 | return -EINVAL; | 486 | return -EINVAL; |
461 | 487 | ||
488 | mutex_lock(&card->conf_mutex); | ||
462 | if ((card->state != CARD_STATE_DOWN) && | 489 | if ((card->state != CARD_STATE_DOWN) && |
463 | (card->state != CARD_STATE_RECOVER)) | 490 | (card->state != CARD_STATE_RECOVER)) { |
464 | return -EPERM; | 491 | rc = -EPERM; |
492 | goto out; | ||
493 | } | ||
465 | 494 | ||
466 | tmp = strsep((char **) &buf, "\n"); | 495 | tmp = strsep((char **) &buf, "\n"); |
467 | if (!strcmp(tmp, "toggle")) { | 496 | if (!strcmp(tmp, "toggle")) { |
@@ -470,10 +499,11 @@ static ssize_t qeth_l3_dev_ipato_enable_store(struct device *dev, | |||
470 | card->ipato.enabled = 1; | 499 | card->ipato.enabled = 1; |
471 | } else if (!strcmp(tmp, "0")) { | 500 | } else if (!strcmp(tmp, "0")) { |
472 | card->ipato.enabled = 0; | 501 | card->ipato.enabled = 0; |
473 | } else { | 502 | } else |
474 | return -EINVAL; | 503 | rc = -EINVAL; |
475 | } | 504 | out: |
476 | return count; | 505 | mutex_unlock(&card->conf_mutex); |
506 | return rc ? rc : count; | ||
477 | } | 507 | } |
478 | 508 | ||
479 | static QETH_DEVICE_ATTR(ipato_enable, enable, 0644, | 509 | static QETH_DEVICE_ATTR(ipato_enable, enable, 0644, |
@@ -497,10 +527,12 @@ static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev, | |||
497 | { | 527 | { |
498 | struct qeth_card *card = dev_get_drvdata(dev); | 528 | struct qeth_card *card = dev_get_drvdata(dev); |
499 | char *tmp; | 529 | char *tmp; |
530 | int rc = 0; | ||
500 | 531 | ||
501 | if (!card) | 532 | if (!card) |
502 | return -EINVAL; | 533 | return -EINVAL; |
503 | 534 | ||
535 | mutex_lock(&card->conf_mutex); | ||
504 | tmp = strsep((char **) &buf, "\n"); | 536 | tmp = strsep((char **) &buf, "\n"); |
505 | if (!strcmp(tmp, "toggle")) { | 537 | if (!strcmp(tmp, "toggle")) { |
506 | card->ipato.invert4 = (card->ipato.invert4)? 0 : 1; | 538 | card->ipato.invert4 = (card->ipato.invert4)? 0 : 1; |
@@ -508,10 +540,10 @@ static ssize_t qeth_l3_dev_ipato_invert4_store(struct device *dev, | |||
508 | card->ipato.invert4 = 1; | 540 | card->ipato.invert4 = 1; |
509 | } else if (!strcmp(tmp, "0")) { | 541 | } else if (!strcmp(tmp, "0")) { |
510 | card->ipato.invert4 = 0; | 542 | card->ipato.invert4 = 0; |
511 | } else { | 543 | } else |
512 | return -EINVAL; | 544 | rc = -EINVAL; |
513 | } | 545 | mutex_unlock(&card->conf_mutex); |
514 | return count; | 546 | return rc ? rc : count; |
515 | } | 547 | } |
516 | 548 | ||
517 | static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644, | 549 | static QETH_DEVICE_ATTR(ipato_invert4, invert4, 0644, |
@@ -593,27 +625,28 @@ static ssize_t qeth_l3_dev_ipato_add_store(const char *buf, size_t count, | |||
593 | struct qeth_ipato_entry *ipatoe; | 625 | struct qeth_ipato_entry *ipatoe; |
594 | u8 addr[16]; | 626 | u8 addr[16]; |
595 | int mask_bits; | 627 | int mask_bits; |
596 | int rc; | 628 | int rc = 0; |
597 | 629 | ||
630 | mutex_lock(&card->conf_mutex); | ||
598 | rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits); | 631 | rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits); |
599 | if (rc) | 632 | if (rc) |
600 | return rc; | 633 | goto out; |
601 | 634 | ||
602 | ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL); | 635 | ipatoe = kzalloc(sizeof(struct qeth_ipato_entry), GFP_KERNEL); |
603 | if (!ipatoe) { | 636 | if (!ipatoe) { |
604 | return -ENOMEM; | 637 | rc = -ENOMEM; |
638 | goto out; | ||
605 | } | 639 | } |
606 | ipatoe->proto = proto; | 640 | ipatoe->proto = proto; |
607 | memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16); | 641 | memcpy(ipatoe->addr, addr, (proto == QETH_PROT_IPV4)? 4:16); |
608 | ipatoe->mask_bits = mask_bits; | 642 | ipatoe->mask_bits = mask_bits; |
609 | 643 | ||
610 | rc = qeth_l3_add_ipato_entry(card, ipatoe); | 644 | rc = qeth_l3_add_ipato_entry(card, ipatoe); |
611 | if (rc) { | 645 | if (rc) |
612 | kfree(ipatoe); | 646 | kfree(ipatoe); |
613 | return rc; | 647 | out: |
614 | } | 648 | mutex_unlock(&card->conf_mutex); |
615 | 649 | return rc ? rc : count; | |
616 | return count; | ||
617 | } | 650 | } |
618 | 651 | ||
619 | static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev, | 652 | static ssize_t qeth_l3_dev_ipato_add4_store(struct device *dev, |
@@ -636,15 +669,14 @@ static ssize_t qeth_l3_dev_ipato_del_store(const char *buf, size_t count, | |||
636 | { | 669 | { |
637 | u8 addr[16]; | 670 | u8 addr[16]; |
638 | int mask_bits; | 671 | int mask_bits; |
639 | int rc; | 672 | int rc = 0; |
640 | 673 | ||
674 | mutex_lock(&card->conf_mutex); | ||
641 | rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits); | 675 | rc = qeth_l3_parse_ipatoe(buf, proto, addr, &mask_bits); |
642 | if (rc) | 676 | if (!rc) |
643 | return rc; | 677 | qeth_l3_del_ipato_entry(card, proto, addr, mask_bits); |
644 | 678 | mutex_unlock(&card->conf_mutex); | |
645 | qeth_l3_del_ipato_entry(card, proto, addr, mask_bits); | 679 | return rc ? rc : count; |
646 | |||
647 | return count; | ||
648 | } | 680 | } |
649 | 681 | ||
650 | static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev, | 682 | static ssize_t qeth_l3_dev_ipato_del4_store(struct device *dev, |
@@ -677,10 +709,12 @@ static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev, | |||
677 | { | 709 | { |
678 | struct qeth_card *card = dev_get_drvdata(dev); | 710 | struct qeth_card *card = dev_get_drvdata(dev); |
679 | char *tmp; | 711 | char *tmp; |
712 | int rc = 0; | ||
680 | 713 | ||
681 | if (!card) | 714 | if (!card) |
682 | return -EINVAL; | 715 | return -EINVAL; |
683 | 716 | ||
717 | mutex_lock(&card->conf_mutex); | ||
684 | tmp = strsep((char **) &buf, "\n"); | 718 | tmp = strsep((char **) &buf, "\n"); |
685 | if (!strcmp(tmp, "toggle")) { | 719 | if (!strcmp(tmp, "toggle")) { |
686 | card->ipato.invert6 = (card->ipato.invert6)? 0 : 1; | 720 | card->ipato.invert6 = (card->ipato.invert6)? 0 : 1; |
@@ -688,10 +722,10 @@ static ssize_t qeth_l3_dev_ipato_invert6_store(struct device *dev, | |||
688 | card->ipato.invert6 = 1; | 722 | card->ipato.invert6 = 1; |
689 | } else if (!strcmp(tmp, "0")) { | 723 | } else if (!strcmp(tmp, "0")) { |
690 | card->ipato.invert6 = 0; | 724 | card->ipato.invert6 = 0; |
691 | } else { | 725 | } else |
692 | return -EINVAL; | 726 | rc = -EINVAL; |
693 | } | 727 | mutex_unlock(&card->conf_mutex); |
694 | return count; | 728 | return rc ? rc : count; |
695 | } | 729 | } |
696 | 730 | ||
697 | static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644, | 731 | static QETH_DEVICE_ATTR(ipato_invert6, invert6, 0644, |
@@ -813,15 +847,12 @@ static ssize_t qeth_l3_dev_vipa_add_store(const char *buf, size_t count, | |||
813 | u8 addr[16] = {0, }; | 847 | u8 addr[16] = {0, }; |
814 | int rc; | 848 | int rc; |
815 | 849 | ||
850 | mutex_lock(&card->conf_mutex); | ||
816 | rc = qeth_l3_parse_vipae(buf, proto, addr); | 851 | rc = qeth_l3_parse_vipae(buf, proto, addr); |
817 | if (rc) | 852 | if (!rc) |
818 | return rc; | 853 | rc = qeth_l3_add_vipa(card, proto, addr); |
819 | 854 | mutex_unlock(&card->conf_mutex); | |
820 | rc = qeth_l3_add_vipa(card, proto, addr); | 855 | return rc ? rc : count; |
821 | if (rc) | ||
822 | return rc; | ||
823 | |||
824 | return count; | ||
825 | } | 856 | } |
826 | 857 | ||
827 | static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev, | 858 | static ssize_t qeth_l3_dev_vipa_add4_store(struct device *dev, |
@@ -845,13 +876,12 @@ static ssize_t qeth_l3_dev_vipa_del_store(const char *buf, size_t count, | |||
845 | u8 addr[16]; | 876 | u8 addr[16]; |
846 | int rc; | 877 | int rc; |
847 | 878 | ||
879 | mutex_lock(&card->conf_mutex); | ||
848 | rc = qeth_l3_parse_vipae(buf, proto, addr); | 880 | rc = qeth_l3_parse_vipae(buf, proto, addr); |
849 | if (rc) | 881 | if (!rc) |
850 | return rc; | 882 | qeth_l3_del_vipa(card, proto, addr); |
851 | 883 | mutex_unlock(&card->conf_mutex); | |
852 | qeth_l3_del_vipa(card, proto, addr); | 884 | return rc ? rc : count; |
853 | |||
854 | return count; | ||
855 | } | 885 | } |
856 | 886 | ||
857 | static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev, | 887 | static ssize_t qeth_l3_dev_vipa_del4_store(struct device *dev, |
@@ -979,15 +1009,12 @@ static ssize_t qeth_l3_dev_rxip_add_store(const char *buf, size_t count, | |||
979 | u8 addr[16] = {0, }; | 1009 | u8 addr[16] = {0, }; |
980 | int rc; | 1010 | int rc; |
981 | 1011 | ||
1012 | mutex_lock(&card->conf_mutex); | ||
982 | rc = qeth_l3_parse_rxipe(buf, proto, addr); | 1013 | rc = qeth_l3_parse_rxipe(buf, proto, addr); |
983 | if (rc) | 1014 | if (!rc) |
984 | return rc; | 1015 | rc = qeth_l3_add_rxip(card, proto, addr); |
985 | 1016 | mutex_unlock(&card->conf_mutex); | |
986 | rc = qeth_l3_add_rxip(card, proto, addr); | 1017 | return rc ? rc : count; |
987 | if (rc) | ||
988 | return rc; | ||
989 | |||
990 | return count; | ||
991 | } | 1018 | } |
992 | 1019 | ||
993 | static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev, | 1020 | static ssize_t qeth_l3_dev_rxip_add4_store(struct device *dev, |
@@ -1011,13 +1038,12 @@ static ssize_t qeth_l3_dev_rxip_del_store(const char *buf, size_t count, | |||
1011 | u8 addr[16]; | 1038 | u8 addr[16]; |
1012 | int rc; | 1039 | int rc; |
1013 | 1040 | ||
1041 | mutex_lock(&card->conf_mutex); | ||
1014 | rc = qeth_l3_parse_rxipe(buf, proto, addr); | 1042 | rc = qeth_l3_parse_rxipe(buf, proto, addr); |
1015 | if (rc) | 1043 | if (!rc) |
1016 | return rc; | 1044 | qeth_l3_del_rxip(card, proto, addr); |
1017 | 1045 | mutex_unlock(&card->conf_mutex); | |
1018 | qeth_l3_del_rxip(card, proto, addr); | 1046 | return rc ? rc : count; |
1019 | |||
1020 | return count; | ||
1021 | } | 1047 | } |
1022 | 1048 | ||
1023 | static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev, | 1049 | static ssize_t qeth_l3_dev_rxip_del4_store(struct device *dev, |