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