diff options
Diffstat (limited to 'arch/s390/mm/extmem.c')
-rw-r--r-- | arch/s390/mm/extmem.c | 38 |
1 files changed, 18 insertions, 20 deletions
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 226275d5c4f6..9e9bc48463a5 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c | |||
@@ -14,12 +14,13 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/bootmem.h> | 16 | #include <linux/bootmem.h> |
17 | #include <linux/ctype.h> | ||
17 | #include <asm/page.h> | 18 | #include <asm/page.h> |
18 | #include <asm/ebcdic.h> | 19 | #include <asm/ebcdic.h> |
19 | #include <asm/errno.h> | 20 | #include <asm/errno.h> |
20 | #include <asm/extmem.h> | 21 | #include <asm/extmem.h> |
21 | #include <asm/cpcmd.h> | 22 | #include <asm/cpcmd.h> |
22 | #include <linux/ctype.h> | 23 | #include <asm/setup.h> |
23 | 24 | ||
24 | #define DCSS_DEBUG /* Debug messages on/off */ | 25 | #define DCSS_DEBUG /* Debug messages on/off */ |
25 | 26 | ||
@@ -77,15 +78,11 @@ struct dcss_segment { | |||
77 | int segcnt; | 78 | int segcnt; |
78 | }; | 79 | }; |
79 | 80 | ||
80 | static DEFINE_SPINLOCK(dcss_lock); | 81 | static DEFINE_MUTEX(dcss_lock); |
81 | static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list); | 82 | static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list); |
82 | static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", | 83 | static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", |
83 | "EW/EN-MIXED" }; | 84 | "EW/EN-MIXED" }; |
84 | 85 | ||
85 | extern struct { | ||
86 | unsigned long addr, size, type; | ||
87 | } memory_chunk[MEMORY_CHUNKS]; | ||
88 | |||
89 | /* | 86 | /* |
90 | * Create the 8 bytes, ebcdic VM segment name from | 87 | * Create the 8 bytes, ebcdic VM segment name from |
91 | * an ascii name. | 88 | * an ascii name. |
@@ -117,7 +114,7 @@ segment_by_name (char *name) | |||
117 | struct list_head *l; | 114 | struct list_head *l; |
118 | struct dcss_segment *tmp, *retval = NULL; | 115 | struct dcss_segment *tmp, *retval = NULL; |
119 | 116 | ||
120 | assert_spin_locked(&dcss_lock); | 117 | BUG_ON(!mutex_is_locked(&dcss_lock)); |
121 | dcss_mkname (name, dcss_name); | 118 | dcss_mkname (name, dcss_name); |
122 | list_for_each (l, &dcss_list) { | 119 | list_for_each (l, &dcss_list) { |
123 | tmp = list_entry (l, struct dcss_segment, list); | 120 | tmp = list_entry (l, struct dcss_segment, list); |
@@ -249,8 +246,8 @@ segment_overlaps_storage(struct dcss_segment *seg) | |||
249 | { | 246 | { |
250 | int i; | 247 | int i; |
251 | 248 | ||
252 | for (i=0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { | 249 | for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { |
253 | if (memory_chunk[i].type != 0) | 250 | if (memory_chunk[i].type != CHUNK_READ_WRITE) |
254 | continue; | 251 | continue; |
255 | if ((memory_chunk[i].addr >> 20) > (seg->end >> 20)) | 252 | if ((memory_chunk[i].addr >> 20) > (seg->end >> 20)) |
256 | continue; | 253 | continue; |
@@ -272,7 +269,7 @@ segment_overlaps_others (struct dcss_segment *seg) | |||
272 | struct list_head *l; | 269 | struct list_head *l; |
273 | struct dcss_segment *tmp; | 270 | struct dcss_segment *tmp; |
274 | 271 | ||
275 | assert_spin_locked(&dcss_lock); | 272 | BUG_ON(!mutex_is_locked(&dcss_lock)); |
276 | list_for_each(l, &dcss_list) { | 273 | list_for_each(l, &dcss_list) { |
277 | tmp = list_entry(l, struct dcss_segment, list); | 274 | tmp = list_entry(l, struct dcss_segment, list); |
278 | if ((tmp->start_addr >> 20) > (seg->end >> 20)) | 275 | if ((tmp->start_addr >> 20) > (seg->end >> 20)) |
@@ -429,7 +426,7 @@ segment_load (char *name, int do_nonshared, unsigned long *addr, | |||
429 | if (!MACHINE_IS_VM) | 426 | if (!MACHINE_IS_VM) |
430 | return -ENOSYS; | 427 | return -ENOSYS; |
431 | 428 | ||
432 | spin_lock (&dcss_lock); | 429 | mutex_lock(&dcss_lock); |
433 | seg = segment_by_name (name); | 430 | seg = segment_by_name (name); |
434 | if (seg == NULL) | 431 | if (seg == NULL) |
435 | rc = __segment_load (name, do_nonshared, addr, end); | 432 | rc = __segment_load (name, do_nonshared, addr, end); |
@@ -444,7 +441,7 @@ segment_load (char *name, int do_nonshared, unsigned long *addr, | |||
444 | rc = -EPERM; | 441 | rc = -EPERM; |
445 | } | 442 | } |
446 | } | 443 | } |
447 | spin_unlock (&dcss_lock); | 444 | mutex_unlock(&dcss_lock); |
448 | return rc; | 445 | return rc; |
449 | } | 446 | } |
450 | 447 | ||
@@ -467,7 +464,7 @@ segment_modify_shared (char *name, int do_nonshared) | |||
467 | unsigned long dummy; | 464 | unsigned long dummy; |
468 | int dcss_command, rc, diag_cc; | 465 | int dcss_command, rc, diag_cc; |
469 | 466 | ||
470 | spin_lock (&dcss_lock); | 467 | mutex_lock(&dcss_lock); |
471 | seg = segment_by_name (name); | 468 | seg = segment_by_name (name); |
472 | if (seg == NULL) { | 469 | if (seg == NULL) { |
473 | rc = -EINVAL; | 470 | rc = -EINVAL; |
@@ -508,7 +505,7 @@ segment_modify_shared (char *name, int do_nonshared) | |||
508 | &dummy, &dummy); | 505 | &dummy, &dummy); |
509 | kfree(seg); | 506 | kfree(seg); |
510 | out_unlock: | 507 | out_unlock: |
511 | spin_unlock(&dcss_lock); | 508 | mutex_unlock(&dcss_lock); |
512 | return rc; | 509 | return rc; |
513 | } | 510 | } |
514 | 511 | ||
@@ -526,7 +523,7 @@ segment_unload(char *name) | |||
526 | if (!MACHINE_IS_VM) | 523 | if (!MACHINE_IS_VM) |
527 | return; | 524 | return; |
528 | 525 | ||
529 | spin_lock(&dcss_lock); | 526 | mutex_lock(&dcss_lock); |
530 | seg = segment_by_name (name); | 527 | seg = segment_by_name (name); |
531 | if (seg == NULL) { | 528 | if (seg == NULL) { |
532 | PRINT_ERR ("could not find segment %s in segment_unload, " | 529 | PRINT_ERR ("could not find segment %s in segment_unload, " |
@@ -540,7 +537,7 @@ segment_unload(char *name) | |||
540 | kfree(seg); | 537 | kfree(seg); |
541 | } | 538 | } |
542 | out_unlock: | 539 | out_unlock: |
543 | spin_unlock(&dcss_lock); | 540 | mutex_unlock(&dcss_lock); |
544 | } | 541 | } |
545 | 542 | ||
546 | /* | 543 | /* |
@@ -559,12 +556,13 @@ segment_save(char *name) | |||
559 | if (!MACHINE_IS_VM) | 556 | if (!MACHINE_IS_VM) |
560 | return; | 557 | return; |
561 | 558 | ||
562 | spin_lock(&dcss_lock); | 559 | mutex_lock(&dcss_lock); |
563 | seg = segment_by_name (name); | 560 | seg = segment_by_name (name); |
564 | 561 | ||
565 | if (seg == NULL) { | 562 | if (seg == NULL) { |
566 | PRINT_ERR ("could not find segment %s in segment_save, please report to linux390@de.ibm.com\n",name); | 563 | PRINT_ERR("could not find segment %s in segment_save, please " |
567 | return; | 564 | "report to linux390@de.ibm.com\n", name); |
565 | goto out; | ||
568 | } | 566 | } |
569 | 567 | ||
570 | startpfn = seg->start_addr >> PAGE_SHIFT; | 568 | startpfn = seg->start_addr >> PAGE_SHIFT; |
@@ -591,7 +589,7 @@ segment_save(char *name) | |||
591 | goto out; | 589 | goto out; |
592 | } | 590 | } |
593 | out: | 591 | out: |
594 | spin_unlock(&dcss_lock); | 592 | mutex_unlock(&dcss_lock); |
595 | } | 593 | } |
596 | 594 | ||
597 | EXPORT_SYMBOL(segment_load); | 595 | EXPORT_SYMBOL(segment_load); |