Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6

* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6:
[S390] fill out file list in s390 MAINTAINERS entry
[S390] Add support for LZO-compressed kernels.
[S390] cmm: get rid of CMM_PROC config option
[S390] cmm: remove superfluous EXPORT_SYMBOLs plus cleanups
[S390] dasd: unit check handling during internal cio I/O
[S390] cio: unit check handling during internal I/O
[S390] ccwgroup: add locking around drvdata access
[S390] cio: remove stsch
[S390] spp: remove KVM_AWARE_CMF config option
[S390] kprobes: forbid probing of stnsm/stosm/epsw
[S390] spp: fix compilation for CONFIG_32BIT
[S390] atomic: implement atomic64_dec_if_positive
[S390] cmm: fix crash on module unload

+135 -113
+3
MAINTAINERS
··· 4836 S: Supported 4837 F: arch/s390/ 4838 F: drivers/s390/ 4839 4840 S390 NETWORK DRIVERS 4841 M: Ursula Braun <ursula.braun@de.ibm.com>
··· 4836 S: Supported 4837 F: arch/s390/ 4838 F: drivers/s390/ 4839 + F: fs/partitions/ibm.c 4840 + F: Documentation/s390/ 4841 + F: Documentation/DocBook/s390* 4842 4843 S390 NETWORK DRIVERS 4844 M: Ursula Braun <ursula.braun@de.ibm.com>
+1 -7
arch/s390/Kconfig
··· 102 select HAVE_KERNEL_GZIP 103 select HAVE_KERNEL_BZIP2 104 select HAVE_KERNEL_LZMA 105 select ARCH_INLINE_SPIN_TRYLOCK 106 select ARCH_INLINE_SPIN_TRYLOCK_BH 107 select ARCH_INLINE_SPIN_LOCK ··· 479 allows an external monitor to balance memory of many systems. 480 Everybody who wants to run Linux under VM should select this 481 option. 482 - 483 - config CMM_PROC 484 - bool "/proc interface to cooperative memory management" 485 - depends on CMM 486 - help 487 - Select this option to enable the /proc interface to the 488 - cooperative memory management. 489 490 config CMM_IUCV 491 bool "IUCV special message interface to cooperative memory management"
··· 102 select HAVE_KERNEL_GZIP 103 select HAVE_KERNEL_BZIP2 104 select HAVE_KERNEL_LZMA 105 + select HAVE_KERNEL_LZO 106 select ARCH_INLINE_SPIN_TRYLOCK 107 select ARCH_INLINE_SPIN_TRYLOCK_BH 108 select ARCH_INLINE_SPIN_LOCK ··· 478 allows an external monitor to balance memory of many systems. 479 Everybody who wants to run Linux under VM should select this 480 option. 481 482 config CMM_IUCV 483 bool "IUCV special message interface to cooperative memory management"
+4 -1
arch/s390/boot/compressed/Makefile
··· 7 BITS := $(if $(CONFIG_64BIT),64,31) 8 9 targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \ 10 - vmlinux.bin.lzma misc.o piggy.o sizes.h head$(BITS).o 11 12 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 13 KBUILD_CFLAGS += $(cflags-y) ··· 47 suffix-$(CONFIG_KERNEL_GZIP) := gz 48 suffix-$(CONFIG_KERNEL_BZIP2) := bz2 49 suffix-$(CONFIG_KERNEL_LZMA) := lzma 50 51 $(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) 52 $(call if_changed,gzip) ··· 55 $(call if_changed,bzip2) 56 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) 57 $(call if_changed,lzma) 58 59 LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T 60 $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)
··· 7 BITS := $(if $(CONFIG_64BIT),64,31) 8 9 targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 \ 10 + vmlinux.bin.lzma vmlinux.bin.lzo misc.o piggy.o sizes.h head$(BITS).o 11 12 KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 13 KBUILD_CFLAGS += $(cflags-y) ··· 47 suffix-$(CONFIG_KERNEL_GZIP) := gz 48 suffix-$(CONFIG_KERNEL_BZIP2) := bz2 49 suffix-$(CONFIG_KERNEL_LZMA) := lzma 50 + suffix-$(CONFIG_KERNEL_LZO) := lzo 51 52 $(obj)/vmlinux.bin.gz: $(vmlinux.bin.all-y) 53 $(call if_changed,gzip) ··· 54 $(call if_changed,bzip2) 55 $(obj)/vmlinux.bin.lzma: $(vmlinux.bin.all-y) 56 $(call if_changed,lzma) 57 + $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.all-y) 58 + $(call if_changed,lzo) 59 60 LDFLAGS_piggy.o := -r --format binary --oformat $(LD_BFD) -T 61 $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y)
+4
arch/s390/boot/compressed/misc.c
··· 50 #include "../../../../lib/decompress_unlzma.c" 51 #endif 52 53 extern _sclp_print_early(const char *); 54 55 int puts(const char *s)
··· 50 #include "../../../../lib/decompress_unlzma.c" 51 #endif 52 53 + #ifdef CONFIG_KERNEL_LZO 54 + #include "../../../../lib/decompress_unlzo.c" 55 + #endif 56 + 57 extern _sclp_print_early(const char *); 58 59 int puts(const char *s)
+19
arch/s390/include/asm/atomic.h
··· 15 16 #include <linux/compiler.h> 17 #include <linux/types.h> 18 19 #define ATOMIC_INIT(i) { (i) } 20 ··· 275 static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) 276 { 277 long long c, old; 278 c = atomic64_read(v); 279 for (;;) { 280 if (unlikely(c == u)) ··· 286 c = old; 287 } 288 return c != u; 289 } 290 291 #define atomic64_add(_i, _v) atomic64_add_return(_i, _v)
··· 15 16 #include <linux/compiler.h> 17 #include <linux/types.h> 18 + #include <asm/system.h> 19 20 #define ATOMIC_INIT(i) { (i) } 21 ··· 274 static inline int atomic64_add_unless(atomic64_t *v, long long a, long long u) 275 { 276 long long c, old; 277 + 278 c = atomic64_read(v); 279 for (;;) { 280 if (unlikely(c == u)) ··· 284 c = old; 285 } 286 return c != u; 287 + } 288 + 289 + static inline long long atomic64_dec_if_positive(atomic64_t *v) 290 + { 291 + long long c, old, dec; 292 + 293 + c = atomic64_read(v); 294 + for (;;) { 295 + dec = c - 1; 296 + if (unlikely(dec < 0)) 297 + break; 298 + old = atomic64_cmpxchg((v), c, dec); 299 + if (likely(old == c)) 300 + break; 301 + c = old; 302 + } 303 + return dec; 304 } 305 306 #define atomic64_add(_i, _v) atomic64_add_return(_i, _v)
+10
arch/s390/include/asm/ccwdev.h
··· 91 void (*handler) (struct ccw_device *, unsigned long, struct irb *); 92 }; 93 94 95 /** 96 * struct ccw driver - device driver for channel attached devices ··· 115 * @freeze: callback for freezing during hibernation snapshotting 116 * @thaw: undo work done in @freeze 117 * @restore: callback for restoring after hibernation 118 * @driver: embedded device driver structure 119 * @name: device driver name 120 */ ··· 133 int (*freeze)(struct ccw_device *); 134 int (*thaw) (struct ccw_device *); 135 int (*restore)(struct ccw_device *); 136 struct device_driver driver; 137 char *name; 138 };
··· 91 void (*handler) (struct ccw_device *, unsigned long, struct irb *); 92 }; 93 94 + /* 95 + * Possible CIO actions triggered by the unit check handler. 96 + */ 97 + enum uc_todo { 98 + UC_TODO_RETRY, 99 + UC_TODO_RETRY_ON_NEW_PATH, 100 + UC_TODO_STOP 101 + }; 102 103 /** 104 * struct ccw driver - device driver for channel attached devices ··· 107 * @freeze: callback for freezing during hibernation snapshotting 108 * @thaw: undo work done in @freeze 109 * @restore: callback for restoring after hibernation 110 + * @uc_handler: callback for unit check handler 111 * @driver: embedded device driver structure 112 * @name: device driver name 113 */ ··· 124 int (*freeze)(struct ccw_device *); 125 int (*thaw) (struct ccw_device *); 126 int (*restore)(struct ccw_device *); 127 + enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *); 128 struct device_driver driver; 129 char *name; 130 };
+2 -2
arch/s390/kernel/asm-offsets.c
··· 132 DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); 133 DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); 134 DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func)); 135 - DEFINE(__LC_SIE_HOOK, offsetof(struct _lowcore, sie_hook)); 136 - DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp)); 137 DEFINE(__LC_IRB, offsetof(struct _lowcore, irb)); 138 DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area)); 139 DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area)); ··· 152 DEFINE(__LC_FP_CREG_SAVE_AREA, offsetof(struct _lowcore, fpt_creg_save_area)); 153 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr)); 154 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data)); 155 #endif /* CONFIG_32BIT */ 156 return 0; 157 }
··· 132 DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); 133 DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); 134 DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func)); 135 DEFINE(__LC_IRB, offsetof(struct _lowcore, irb)); 136 DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area)); 137 DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area)); ··· 154 DEFINE(__LC_FP_CREG_SAVE_AREA, offsetof(struct _lowcore, fpt_creg_save_area)); 155 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr)); 156 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data)); 157 + DEFINE(__LC_SIE_HOOK, offsetof(struct _lowcore, sie_hook)); 158 + DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp)); 159 #endif /* CONFIG_32BIT */ 160 return 0; 161 }
+1 -1
arch/s390/kernel/entry64.S
··· 65 ltgr %r3,%r3 66 jz 0f 67 basr %r14,%r3 68 - 0: 69 #endif 70 .endm 71
··· 65 ltgr %r3,%r3 66 jz 0f 67 basr %r14,%r3 68 + 0: 69 #endif 70 .endm 71
+3
arch/s390/kernel/kprobes.c
··· 63 case 0x0b: /* bsm */ 64 case 0x83: /* diag */ 65 case 0x44: /* ex */ 66 return -EINVAL; 67 } 68 switch (*(__u16 *) instruction) { ··· 74 case 0xb258: /* bsg */ 75 case 0xb218: /* pc */ 76 case 0xb228: /* pt */ 77 return -EINVAL; 78 } 79 return 0;
··· 63 case 0x0b: /* bsm */ 64 case 0x83: /* diag */ 65 case 0x44: /* ex */ 66 + case 0xac: /* stnsm */ 67 + case 0xad: /* stosm */ 68 return -EINVAL; 69 } 70 switch (*(__u16 *) instruction) { ··· 72 case 0xb258: /* bsg */ 73 case 0xb218: /* pc */ 74 case 0xb228: /* pt */ 75 + case 0xb98d: /* epsw */ 76 return -EINVAL; 77 } 78 return 0;
+1 -1
arch/s390/kernel/setup.c
··· 401 lc->io_new_psw.mask = psw_kernel_bits; 402 lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; 403 lc->clock_comparator = -1ULL; 404 - lc->cmf_hpp = -1ULL; 405 lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; 406 lc->async_stack = (unsigned long) 407 __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; ··· 417 __ctl_set_bit(14, 29); 418 } 419 #else 420 lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0]; 421 #endif 422 lc->sync_enter_timer = S390_lowcore.sync_enter_timer;
··· 401 lc->io_new_psw.mask = psw_kernel_bits; 402 lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; 403 lc->clock_comparator = -1ULL; 404 lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; 405 lc->async_stack = (unsigned long) 406 __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; ··· 418 __ctl_set_bit(14, 29); 419 } 420 #else 421 + lc->cmf_hpp = -1ULL; 422 lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0]; 423 #endif 424 lc->sync_enter_timer = S390_lowcore.sync_enter_timer;
-11
arch/s390/kvm/Kconfig
··· 33 34 If unsure, say N. 35 36 - config KVM_AWARE_CMF 37 - depends on KVM 38 - bool "KVM aware sampling" 39 - ---help--- 40 - This option enhances the sampling data from the CPU Measurement 41 - Facility with additional information, that allows to distinguish 42 - guest(s) and host when using the kernel based virtual machine 43 - functionality. 44 - 45 - If unsure, say N. 46 - 47 # OK, it's a little counter-intuitive to do this, but it puts it neatly under 48 # the virtualization menu. 49 source drivers/vhost/Kconfig
··· 33 34 If unsure, say N. 35 36 # OK, it's a little counter-intuitive to do this, but it puts it neatly under 37 # the virtualization menu. 38 source drivers/vhost/Kconfig
+1 -3
arch/s390/kvm/sie64a.S
··· 32 33 34 .macro SPP newpp 35 - #ifdef CONFIG_KVM_AWARE_CMF 36 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP 37 jz 0f 38 .insn s,0xb2800000,\newpp 39 - 0: 40 - #endif 41 .endm 42 43 sie_irq_handler:
··· 32 33 34 .macro SPP newpp 35 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP 36 jz 0f 37 .insn s,0xb2800000,\newpp 38 + 0: 39 .endm 40 41 sie_irq_handler:
+39 -72
arch/s390/mm/cmm.c
··· 1 /* 2 - * arch/s390/mm/cmm.c 3 - * 4 - * S390 version 5 - * Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 - * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) 7 - * 8 * Collaborative memory management interface. 9 */ 10 11 #include <linux/errno.h> ··· 18 #include <linux/kthread.h> 19 #include <linux/oom.h> 20 #include <linux/suspend.h> 21 22 #include <asm/pgalloc.h> 23 - #include <asm/uaccess.h> 24 #include <asm/diag.h> 25 26 static char *sender = "VMRMSVM"; ··· 51 static DEFINE_SPINLOCK(cmm_lock); 52 53 static struct task_struct *cmm_thread_ptr; 54 - static wait_queue_head_t cmm_thread_wait; 55 - static struct timer_list cmm_timer; 56 57 static void cmm_timer_fn(unsigned long); 58 static void cmm_set_timer(void); 59 60 - static long 61 - cmm_alloc_pages(long nr, long *counter, struct cmm_page_array **list) 62 { 63 struct cmm_page_array *pa, *npa; 64 unsigned long addr; ··· 97 return nr; 98 } 99 100 - static long 101 - cmm_free_pages(long nr, long *counter, struct cmm_page_array **list) 102 { 103 struct cmm_page_array *pa; 104 unsigned long addr; ··· 137 } 138 139 static struct notifier_block cmm_oom_nb = { 140 - .notifier_call = cmm_oom_notify 141 }; 142 143 - static int 144 - cmm_thread(void *dummy) 145 { 146 int rc; 147 ··· 166 cmm_timed_pages_target = cmm_timed_pages; 167 } else if (cmm_timed_pages_target < cmm_timed_pages) { 168 cmm_free_pages(1, &cmm_timed_pages, 169 - &cmm_timed_page_list); 170 } 171 if (cmm_timed_pages > 0 && !timer_pending(&cmm_timer)) 172 cmm_set_timer(); ··· 174 return 0; 175 } 176 177 - static void 178 - cmm_kick_thread(void) 179 { 180 wake_up(&cmm_thread_wait); 181 } 182 183 - static void 184 - cmm_set_timer(void) 185 { 186 if (cmm_timed_pages_target <= 0 || cmm_timeout_seconds <= 0) { 187 if (timer_pending(&cmm_timer)) ··· 196 add_timer(&cmm_timer); 197 } 198 199 - static void 200 - cmm_timer_fn(unsigned long ignored) 201 { 202 long nr; 203 ··· 209 cmm_set_timer(); 210 } 211 212 - void 213 - cmm_set_pages(long nr) 214 { 215 cmm_pages_target = nr; 216 cmm_kick_thread(); 217 } 218 219 - long 220 - cmm_get_pages(void) 221 { 222 return cmm_pages; 223 } 224 225 - void 226 - cmm_add_timed_pages(long nr) 227 { 228 cmm_timed_pages_target += nr; 229 cmm_kick_thread(); 230 } 231 232 - long 233 - cmm_get_timed_pages(void) 234 { 235 return cmm_timed_pages; 236 } 237 238 - void 239 - cmm_set_timeout(long nr, long seconds) 240 { 241 cmm_timeout_pages = nr; 242 cmm_timeout_seconds = seconds; 243 cmm_set_timer(); 244 } 245 246 - static int 247 - cmm_skip_blanks(char *cp, char **endp) 248 { 249 char *str; 250 251 - for (str = cp; *str == ' ' || *str == '\t'; str++); 252 *endp = str; 253 return str != cp; 254 } 255 256 - #ifdef CONFIG_CMM_PROC 257 - 258 static struct ctl_table cmm_table[]; 259 260 - static int 261 - cmm_pages_handler(ctl_table *ctl, int write, 262 - void __user *buffer, size_t *lenp, loff_t *ppos) 263 { 264 char buf[16], *p; 265 long nr; ··· 290 return 0; 291 } 292 293 - static int 294 - cmm_timeout_handler(ctl_table *ctl, int write, 295 - void __user *buffer, size_t *lenp, loff_t *ppos) 296 { 297 char buf[64], *p; 298 long nr, seconds; ··· 354 }, 355 { } 356 }; 357 - #endif 358 359 #ifdef CONFIG_CMM_IUCV 360 #define SMSG_PREFIX "CMM" 361 - static void 362 - cmm_smsg_target(const char *from, char *msg) 363 { 364 long nr, seconds; 365 ··· 427 .notifier_call = cmm_power_event, 428 }; 429 430 - static int 431 - cmm_init (void) 432 { 433 int rc = -ENOMEM; 434 435 - #ifdef CONFIG_CMM_PROC 436 cmm_sysctl_header = register_sysctl_table(cmm_dir_table); 437 if (!cmm_sysctl_header) 438 goto out_sysctl; 439 - #endif 440 #ifdef CONFIG_CMM_IUCV 441 rc = smsg_register_callback(SMSG_PREFIX, cmm_smsg_target); 442 if (rc < 0) ··· 445 rc = register_pm_notifier(&cmm_power_notifier); 446 if (rc) 447 goto out_pm; 448 - init_waitqueue_head(&cmm_thread_wait); 449 - init_timer(&cmm_timer); 450 cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); 451 rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0; 452 if (rc) ··· 460 smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target); 461 out_smsg: 462 #endif 463 - #ifdef CONFIG_CMM_PROC 464 unregister_sysctl_table(cmm_sysctl_header); 465 out_sysctl: 466 - #endif 467 return rc; 468 } 469 470 - static void 471 - cmm_exit(void) 472 { 473 - kthread_stop(cmm_thread_ptr); 474 - unregister_pm_notifier(&cmm_power_notifier); 475 - unregister_oom_notifier(&cmm_oom_nb); 476 - cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list); 477 - cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list); 478 - #ifdef CONFIG_CMM_PROC 479 unregister_sysctl_table(cmm_sysctl_header); 480 - #endif 481 #ifdef CONFIG_CMM_IUCV 482 smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target); 483 #endif 484 } 485 - 486 - module_init(cmm_init); 487 module_exit(cmm_exit); 488 - 489 - EXPORT_SYMBOL(cmm_set_pages); 490 - EXPORT_SYMBOL(cmm_get_pages); 491 - EXPORT_SYMBOL(cmm_add_timed_pages); 492 - EXPORT_SYMBOL(cmm_get_timed_pages); 493 - EXPORT_SYMBOL(cmm_set_timeout); 494 495 MODULE_LICENSE("GPL");
··· 1 /* 2 * Collaborative memory management interface. 3 + * 4 + * Copyright IBM Corp 2003,2010 5 + * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>, 6 + * 7 */ 8 9 #include <linux/errno.h> ··· 20 #include <linux/kthread.h> 21 #include <linux/oom.h> 22 #include <linux/suspend.h> 23 + #include <linux/uaccess.h> 24 25 #include <asm/pgalloc.h> 26 #include <asm/diag.h> 27 28 static char *sender = "VMRMSVM"; ··· 53 static DEFINE_SPINLOCK(cmm_lock); 54 55 static struct task_struct *cmm_thread_ptr; 56 + static DECLARE_WAIT_QUEUE_HEAD(cmm_thread_wait); 57 + static DEFINE_TIMER(cmm_timer, NULL, 0, 0); 58 59 static void cmm_timer_fn(unsigned long); 60 static void cmm_set_timer(void); 61 62 + static long cmm_alloc_pages(long nr, long *counter, 63 + struct cmm_page_array **list) 64 { 65 struct cmm_page_array *pa, *npa; 66 unsigned long addr; ··· 99 return nr; 100 } 101 102 + static long cmm_free_pages(long nr, long *counter, struct cmm_page_array **list) 103 { 104 struct cmm_page_array *pa; 105 unsigned long addr; ··· 140 } 141 142 static struct notifier_block cmm_oom_nb = { 143 + .notifier_call = cmm_oom_notify, 144 }; 145 146 + static int cmm_thread(void *dummy) 147 { 148 int rc; 149 ··· 170 cmm_timed_pages_target = cmm_timed_pages; 171 } else if (cmm_timed_pages_target < cmm_timed_pages) { 172 cmm_free_pages(1, &cmm_timed_pages, 173 + &cmm_timed_page_list); 174 } 175 if (cmm_timed_pages > 0 && !timer_pending(&cmm_timer)) 176 cmm_set_timer(); ··· 178 return 0; 179 } 180 181 + static void cmm_kick_thread(void) 182 { 183 wake_up(&cmm_thread_wait); 184 } 185 186 + static void cmm_set_timer(void) 187 { 188 if (cmm_timed_pages_target <= 0 || cmm_timeout_seconds <= 0) { 189 if (timer_pending(&cmm_timer)) ··· 202 add_timer(&cmm_timer); 203 } 204 205 + static void cmm_timer_fn(unsigned long ignored) 206 { 207 long nr; 208 ··· 216 cmm_set_timer(); 217 } 218 219 + static void cmm_set_pages(long nr) 220 { 221 cmm_pages_target = nr; 222 cmm_kick_thread(); 223 } 224 225 + static long cmm_get_pages(void) 226 { 227 return cmm_pages; 228 } 229 230 + static void cmm_add_timed_pages(long nr) 231 { 232 cmm_timed_pages_target += nr; 233 cmm_kick_thread(); 234 } 235 236 + static long cmm_get_timed_pages(void) 237 { 238 return cmm_timed_pages; 239 } 240 241 + static void cmm_set_timeout(long nr, long seconds) 242 { 243 cmm_timeout_pages = nr; 244 cmm_timeout_seconds = seconds; 245 cmm_set_timer(); 246 } 247 248 + static int cmm_skip_blanks(char *cp, char **endp) 249 { 250 char *str; 251 252 + for (str = cp; *str == ' ' || *str == '\t'; str++) 253 + ; 254 *endp = str; 255 return str != cp; 256 } 257 258 static struct ctl_table cmm_table[]; 259 260 + static int cmm_pages_handler(ctl_table *ctl, int write, void __user *buffer, 261 + size_t *lenp, loff_t *ppos) 262 { 263 char buf[16], *p; 264 long nr; ··· 305 return 0; 306 } 307 308 + static int cmm_timeout_handler(ctl_table *ctl, int write, void __user *buffer, 309 + size_t *lenp, loff_t *ppos) 310 { 311 char buf[64], *p; 312 long nr, seconds; ··· 370 }, 371 { } 372 }; 373 374 #ifdef CONFIG_CMM_IUCV 375 #define SMSG_PREFIX "CMM" 376 + static void cmm_smsg_target(const char *from, char *msg) 377 { 378 long nr, seconds; 379 ··· 445 .notifier_call = cmm_power_event, 446 }; 447 448 + static int cmm_init(void) 449 { 450 int rc = -ENOMEM; 451 452 cmm_sysctl_header = register_sysctl_table(cmm_dir_table); 453 if (!cmm_sysctl_header) 454 goto out_sysctl; 455 #ifdef CONFIG_CMM_IUCV 456 rc = smsg_register_callback(SMSG_PREFIX, cmm_smsg_target); 457 if (rc < 0) ··· 466 rc = register_pm_notifier(&cmm_power_notifier); 467 if (rc) 468 goto out_pm; 469 cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); 470 rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0; 471 if (rc) ··· 483 smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target); 484 out_smsg: 485 #endif 486 unregister_sysctl_table(cmm_sysctl_header); 487 out_sysctl: 488 + del_timer_sync(&cmm_timer); 489 return rc; 490 } 491 + module_init(cmm_init); 492 493 + static void cmm_exit(void) 494 { 495 unregister_sysctl_table(cmm_sysctl_header); 496 #ifdef CONFIG_CMM_IUCV 497 smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target); 498 #endif 499 + unregister_pm_notifier(&cmm_power_notifier); 500 + unregister_oom_notifier(&cmm_oom_nb); 501 + kthread_stop(cmm_thread_ptr); 502 + del_timer_sync(&cmm_timer); 503 + cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list); 504 + cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list); 505 } 506 module_exit(cmm_exit); 507 508 MODULE_LICENSE("GPL");
+23
drivers/s390/block/dasd.c
··· 1186 dasd_schedule_device_bh(device); 1187 } 1188 1189 /* 1190 * If we have an error on a dasd_block layer request then we cancel 1191 * and return all further requests from the same dasd_block as well.
··· 1186 dasd_schedule_device_bh(device); 1187 } 1188 1189 + enum uc_todo dasd_generic_uc_handler(struct ccw_device *cdev, struct irb *irb) 1190 + { 1191 + struct dasd_device *device; 1192 + 1193 + device = dasd_device_from_cdev_locked(cdev); 1194 + 1195 + if (IS_ERR(device)) 1196 + goto out; 1197 + if (test_bit(DASD_FLAG_OFFLINE, &device->flags) || 1198 + device->state != device->target || 1199 + !device->discipline->handle_unsolicited_interrupt){ 1200 + dasd_put_device(device); 1201 + goto out; 1202 + } 1203 + 1204 + dasd_device_clear_timer(device); 1205 + device->discipline->handle_unsolicited_interrupt(device, irb); 1206 + dasd_put_device(device); 1207 + out: 1208 + return UC_TODO_RETRY; 1209 + } 1210 + EXPORT_SYMBOL_GPL(dasd_generic_uc_handler); 1211 + 1212 /* 1213 * If we have an error on a dasd_block layer request then we cancel 1214 * and return all further requests from the same dasd_block as well.
+1
drivers/s390/block/dasd_eckd.c
··· 3436 .freeze = dasd_generic_pm_freeze, 3437 .thaw = dasd_generic_restore_device, 3438 .restore = dasd_generic_restore_device, 3439 }; 3440 3441 /*
··· 3436 .freeze = dasd_generic_pm_freeze, 3437 .thaw = dasd_generic_restore_device, 3438 .restore = dasd_generic_restore_device, 3439 + .uc_handler = dasd_generic_uc_handler, 3440 }; 3441 3442 /*
+1
drivers/s390/block/dasd_int.h
··· 617 void dasd_generic_handle_state_change(struct dasd_device *); 618 int dasd_generic_pm_freeze(struct ccw_device *); 619 int dasd_generic_restore_device(struct ccw_device *); 620 621 int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int); 622 char *dasd_get_sense(struct irb *);
··· 617 void dasd_generic_handle_state_change(struct dasd_device *); 618 int dasd_generic_pm_freeze(struct ccw_device *); 619 int dasd_generic_restore_device(struct ccw_device *); 620 + enum uc_todo dasd_generic_uc_handler(struct ccw_device *, struct irb *); 621 622 int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int); 623 char *dasd_get_sense(struct irb *);
+7
drivers/s390/cio/ccwgroup.c
··· 123 124 for (i = 0; i < gdev->count; i++) { 125 if (gdev->cdev[i]) { 126 if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) 127 dev_set_drvdata(&gdev->cdev[i]->dev, NULL); 128 put_device(&gdev->cdev[i]->dev); 129 } 130 } ··· 264 goto error; 265 } 266 /* Don't allow a device to belong to more than one group. */ 267 if (dev_get_drvdata(&gdev->cdev[i]->dev)) { 268 rc = -EINVAL; 269 goto error; 270 } 271 dev_set_drvdata(&gdev->cdev[i]->dev, gdev); 272 } 273 /* Check for sufficient number of bus ids. */ 274 if (i < num_devices && !curr_buf) { ··· 308 error: 309 for (i = 0; i < num_devices; i++) 310 if (gdev->cdev[i]) { 311 if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) 312 dev_set_drvdata(&gdev->cdev[i]->dev, NULL); 313 put_device(&gdev->cdev[i]->dev); 314 gdev->cdev[i] = NULL; 315 }
··· 123 124 for (i = 0; i < gdev->count; i++) { 125 if (gdev->cdev[i]) { 126 + spin_lock_irq(gdev->cdev[i]->ccwlock); 127 if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) 128 dev_set_drvdata(&gdev->cdev[i]->dev, NULL); 129 + spin_unlock_irq(gdev->cdev[i]->ccwlock); 130 put_device(&gdev->cdev[i]->dev); 131 } 132 } ··· 262 goto error; 263 } 264 /* Don't allow a device to belong to more than one group. */ 265 + spin_lock_irq(gdev->cdev[i]->ccwlock); 266 if (dev_get_drvdata(&gdev->cdev[i]->dev)) { 267 + spin_unlock_irq(gdev->cdev[i]->ccwlock); 268 rc = -EINVAL; 269 goto error; 270 } 271 dev_set_drvdata(&gdev->cdev[i]->dev, gdev); 272 + spin_unlock_irq(gdev->cdev[i]->ccwlock); 273 } 274 /* Check for sufficient number of bus ids. */ 275 if (i < num_devices && !curr_buf) { ··· 303 error: 304 for (i = 0; i < num_devices; i++) 305 if (gdev->cdev[i]) { 306 + spin_lock_irq(gdev->cdev[i]->ccwlock); 307 if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) 308 dev_set_drvdata(&gdev->cdev[i]->dev, NULL); 309 + spin_unlock_irq(gdev->cdev[i]->ccwlock); 310 put_device(&gdev->cdev[i]->dev); 311 gdev->cdev[i] = NULL; 312 }
+15
drivers/s390/cio/ccwreq.c
··· 159 { 160 struct irb *irb = &cdev->private->irb; 161 struct cmd_scsw *scsw = &irb->scsw.cmd; 162 163 /* Perform BASIC SENSE if needed. */ 164 if (ccw_device_accumulate_and_sense(cdev, lcirb)) ··· 179 /* Check for command reject. */ 180 if (irb->ecw[0] & SNS0_CMD_REJECT) 181 return IO_REJECTED; 182 /* Assume that unexpected SENSE data implies an error. */ 183 return IO_STATUS_ERROR; 184 }
··· 159 { 160 struct irb *irb = &cdev->private->irb; 161 struct cmd_scsw *scsw = &irb->scsw.cmd; 162 + enum uc_todo todo; 163 164 /* Perform BASIC SENSE if needed. */ 165 if (ccw_device_accumulate_and_sense(cdev, lcirb)) ··· 178 /* Check for command reject. */ 179 if (irb->ecw[0] & SNS0_CMD_REJECT) 180 return IO_REJECTED; 181 + /* Ask the driver what to do */ 182 + if (cdev->drv && cdev->drv->uc_handler) { 183 + todo = cdev->drv->uc_handler(cdev, lcirb); 184 + switch (todo) { 185 + case UC_TODO_RETRY: 186 + return IO_STATUS_ERROR; 187 + case UC_TODO_RETRY_ON_NEW_PATH: 188 + return IO_PATH_ERROR; 189 + case UC_TODO_STOP: 190 + return IO_REJECTED; 191 + default: 192 + return IO_STATUS_ERROR; 193 + } 194 + } 195 /* Assume that unexpected SENSE data implies an error. */ 196 return IO_STATUS_ERROR; 197 }
-15
drivers/s390/cio/ioasm.h
··· 23 * Some S390 specific IO instructions as inline 24 */ 25 26 - static inline int stsch(struct subchannel_id schid, struct schib *addr) 27 - { 28 - register struct subchannel_id reg1 asm ("1") = schid; 29 - int ccode; 30 - 31 - asm volatile( 32 - " stsch 0(%3)\n" 33 - " ipm %0\n" 34 - " srl %0,28" 35 - : "=d" (ccode), "=m" (*addr) 36 - : "d" (reg1), "a" (addr) 37 - : "cc"); 38 - return ccode; 39 - } 40 - 41 static inline int stsch_err(struct subchannel_id schid, struct schib *addr) 42 { 43 register struct subchannel_id reg1 asm ("1") = schid;
··· 23 * Some S390 specific IO instructions as inline 24 */ 25 26 static inline int stsch_err(struct subchannel_id schid, struct schib *addr) 27 { 28 register struct subchannel_id reg1 asm ("1") = schid;