Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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: (72 commits)
[S390] 3215/3270 console: remove wrong comment
[S390] dasd: remove BKL from extended error reporting code
[S390] vmlogrdr: remove BKL
[S390] vmur: remove BKL
[S390] zcrypt: remove BKL
[S390] 3270: remove BKL
[S390] vmwatchdog: remove lock_kernel() from open() function
[S390] monwriter: remove lock_kernel() from open() function
[S390] monreader: remove lock_kernel() from open() function
[S390] s390: remove unused nfsd #includes
[S390] ftrace: build ftrace.o when CONFIG_FTRACE_SYSCALLS is set for s390
[S390] etr/stp: put correct per cpu variable
[S390] tty3270: move keyboard compat ioctls
[S390] sclp: improve servicability setting
[S390] s390: use change recording override for kernel mapping
[S390] MAINTAINERS: Add s390 drivers block
[S390] use generic sockios.h header file
[S390] use generic termbits.h header file
[S390] smp: remove unused typedef and defines
[S390] cmm: free pages on hibernate.
...

+2797 -2783
+3
MAINTAINERS
··· 3139 3139 F: Documentation/s390/kvm.txt 3140 3140 F: arch/s390/include/asm/kvm* 3141 3141 F: arch/s390/kvm/ 3142 + F: drivers/s390/kvm/ 3142 3143 3143 3144 KEXEC 3144 3145 M: Eric Biederman <ebiederm@xmission.com> ··· 4554 4553 W: http://www.ibm.com/developerworks/linux/linux390/ 4555 4554 S: Supported 4556 4555 F: arch/s390/ 4556 + F: drivers/s390/ 4557 4557 4558 4558 S390 NETWORK DRIVERS 4559 4559 M: Ursula Braun <ursula.braun@de.ibm.com> ··· 4570 4568 M: Ralph Wuerthner <ralph.wuerthner@de.ibm.com> 4571 4569 M: linux390@de.ibm.com 4572 4570 L: linux-s390@vger.kernel.org 4571 + W: http://www.ibm.com/developerworks/linux/linux390/ 4573 4572 S: Supported 4574 4573 F: drivers/s390/crypto/ 4575 4574
-15
arch/s390/Kconfig
··· 220 220 bool 221 221 default y 222 222 223 - config S390_SWITCH_AMODE 224 - bool "Switch kernel/user addressing modes" 225 - help 226 - This option allows to switch the addressing modes of kernel and user 227 - space. The kernel parameter switch_amode=on will enable this feature, 228 - default is disabled. Enabling this (via kernel parameter) on machines 229 - earlier than IBM System z9-109 EC/BC will reduce system performance. 230 - 231 - Note that this option will also be selected by selecting the execute 232 - protection option below. Enabling the execute protection via the 233 - noexec kernel parameter will also switch the addressing modes, 234 - independent of the switch_amode kernel parameter. 235 - 236 - 237 223 config S390_EXEC_PROTECT 238 224 bool "Data execute protection" 239 - select S390_SWITCH_AMODE 240 225 help 241 226 This option allows to enable a buffer overflow protection for user 242 227 space programs and it also selects the addressing mode option above.
-1
arch/s390/defconfig
··· 185 185 CONFIG_COMPAT=y 186 186 CONFIG_SYSVIPC_COMPAT=y 187 187 CONFIG_AUDIT_ARCH=y 188 - CONFIG_S390_SWITCH_AMODE=y 189 188 CONFIG_S390_EXEC_PROTECT=y 190 189 191 190 #
+4 -4
arch/s390/include/asm/atomic.h
··· 21 21 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) 22 22 23 23 #define __CS_LOOP(ptr, op_val, op_string) ({ \ 24 - typeof(ptr->counter) old_val, new_val; \ 24 + int old_val, new_val; \ 25 25 asm volatile( \ 26 26 " l %0,%2\n" \ 27 27 "0: lr %1,%0\n" \ ··· 38 38 #else /* __GNUC__ */ 39 39 40 40 #define __CS_LOOP(ptr, op_val, op_string) ({ \ 41 - typeof(ptr->counter) old_val, new_val; \ 41 + int old_val, new_val; \ 42 42 asm volatile( \ 43 43 " l %0,0(%3)\n" \ 44 44 "0: lr %1,%0\n" \ ··· 143 143 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) 144 144 145 145 #define __CSG_LOOP(ptr, op_val, op_string) ({ \ 146 - typeof(ptr->counter) old_val, new_val; \ 146 + long long old_val, new_val; \ 147 147 asm volatile( \ 148 148 " lg %0,%2\n" \ 149 149 "0: lgr %1,%0\n" \ ··· 160 160 #else /* __GNUC__ */ 161 161 162 162 #define __CSG_LOOP(ptr, op_val, op_string) ({ \ 163 - typeof(ptr->counter) old_val, new_val; \ 163 + long long old_val, new_val; \ 164 164 asm volatile( \ 165 165 " lg %0,0(%3)\n" \ 166 166 "0: lgr %1,%0\n" \
+4
arch/s390/include/asm/ccwdev.h
··· 142 142 extern int ccw_device_set_options_mask(struct ccw_device *, unsigned long); 143 143 extern int ccw_device_set_options(struct ccw_device *, unsigned long); 144 144 extern void ccw_device_clear_options(struct ccw_device *, unsigned long); 145 + int ccw_device_is_pathgroup(struct ccw_device *cdev); 146 + int ccw_device_is_multipath(struct ccw_device *cdev); 145 147 146 148 /* Allow for i/o completion notification after primary interrupt status. */ 147 149 #define CCWDEV_EARLY_NOTIFICATION 0x0001 ··· 153 151 #define CCWDEV_DO_PATHGROUP 0x0004 154 152 /* Allow forced onlining of boxed devices. */ 155 153 #define CCWDEV_ALLOW_FORCE 0x0008 154 + /* Try to use multipath mode. */ 155 + #define CCWDEV_DO_MULTIPATH 0x0010 156 156 157 157 extern int ccw_device_start(struct ccw_device *, struct ccw1 *, 158 158 unsigned long, __u8, unsigned long);
+2 -2
arch/s390/include/asm/mmu_context.h
··· 36 36 mm->context.has_pgste = 1; 37 37 mm->context.alloc_pgste = 1; 38 38 } else { 39 - mm->context.noexec = s390_noexec; 39 + mm->context.noexec = (user_mode == SECONDARY_SPACE_MODE); 40 40 mm->context.has_pgste = 0; 41 41 mm->context.alloc_pgste = 0; 42 42 } ··· 58 58 pgd_t *pgd = mm->pgd; 59 59 60 60 S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); 61 - if (switch_amode) { 61 + if (user_mode != HOME_SPACE_MODE) { 62 62 /* Load primary space page table origin. */ 63 63 pgd = mm->context.noexec ? get_shadow_table(pgd) : pgd; 64 64 S390_lowcore.user_exec_asce = mm->context.asce_bits | __pa(pgd);
+2 -1
arch/s390/include/asm/pgalloc.h
··· 143 143 spin_lock_init(&mm->context.list_lock); 144 144 INIT_LIST_HEAD(&mm->context.crst_list); 145 145 INIT_LIST_HEAD(&mm->context.pgtable_list); 146 - return (pgd_t *) crst_table_alloc(mm, s390_noexec); 146 + return (pgd_t *) 147 + crst_table_alloc(mm, user_mode == SECONDARY_SPACE_MODE); 147 148 } 148 149 #define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd) 149 150
+3 -1
arch/s390/include/asm/pgtable.h
··· 169 169 * STL Segment-Table-Length: Segment-table length (STL+1*16 entries -> up to 2048) 170 170 * 171 171 * A 64 bit pagetable entry of S390 has following format: 172 - * | PFRA |0IP0| OS | 172 + * | PFRA |0IPC| OS | 173 173 * 0000000000111111111122222222223333333333444444444455555555556666 174 174 * 0123456789012345678901234567890123456789012345678901234567890123 175 175 * 176 176 * I Page-Invalid Bit: Page is not available for address-translation 177 177 * P Page-Protection Bit: Store access not possible for page 178 + * C Change-bit override: HW is not required to set change bit 178 179 * 179 180 * A 64 bit segmenttable entry of S390 has following format: 180 181 * | P-table origin | TT ··· 219 218 */ 220 219 221 220 /* Hardware bits in the page table entry */ 221 + #define _PAGE_CO 0x100 /* HW Change-bit override */ 222 222 #define _PAGE_RO 0x200 /* HW read-only bit */ 223 223 #define _PAGE_INVALID 0x400 /* HW invalid bit */ 224 224
+5 -10
arch/s390/include/asm/setup.h
··· 49 49 50 50 void detect_memory_layout(struct mem_chunk chunk[]); 51 51 52 - #ifdef CONFIG_S390_SWITCH_AMODE 53 - extern unsigned int switch_amode; 54 - #else 55 - #define switch_amode (0) 56 - #endif 52 + #define PRIMARY_SPACE_MODE 0 53 + #define ACCESS_REGISTER_MODE 1 54 + #define SECONDARY_SPACE_MODE 2 55 + #define HOME_SPACE_MODE 3 57 56 58 - #ifdef CONFIG_S390_EXEC_PROTECT 59 - extern unsigned int s390_noexec; 60 - #else 61 - #define s390_noexec (0) 62 - #endif 57 + extern unsigned int user_mode; 63 58 64 59 /* 65 60 * Machine features detected in head.S
+10 -44
arch/s390/include/asm/smp.h
··· 1 1 /* 2 - * include/asm-s390/smp.h 3 - * 4 - * S390 version 5 - * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 6 - * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), 7 - * Martin Schwidefsky (schwidefsky@de.ibm.com) 8 - * Heiko Carstens (heiko.carstens@de.ibm.com) 2 + * Copyright IBM Corp. 1999,2009 3 + * Author(s): Denis Joseph Barrow, 4 + * Martin Schwidefsky <schwidefsky@de.ibm.com>, 5 + * Heiko Carstens <heiko.carstens@de.ibm.com>, 9 6 */ 10 7 #ifndef __ASM_SMP_H 11 8 #define __ASM_SMP_H 12 9 13 - #include <linux/threads.h> 14 - #include <linux/cpumask.h> 15 - #include <linux/bitops.h> 10 + #ifdef CONFIG_SMP 16 11 17 - #if defined(__KERNEL__) && defined(CONFIG_SMP) && !defined(__ASSEMBLY__) 18 - 19 - #include <asm/lowcore.h> 20 - #include <asm/sigp.h> 21 - #include <asm/ptrace.h> 22 12 #include <asm/system.h> 23 - 24 - /* 25 - s390 specific smp.c headers 26 - */ 27 - typedef struct 28 - { 29 - int intresting; 30 - sigp_ccode ccode; 31 - __u32 status; 32 - __u16 cpu; 33 - } sigp_info; 13 + #include <asm/sigp.h> 34 14 35 15 extern void machine_restart_smp(char *); 36 16 extern void machine_halt_smp(void); 37 17 extern void machine_power_off_smp(void); 38 18 39 - #define NO_PROC_ID 0xFF /* No processor magic marker */ 40 - 41 - /* 42 - * This magic constant controls our willingness to transfer 43 - * a process across CPUs. Such a transfer incurs misses on the L1 44 - * cache, and on a P6 or P5 with multiple L2 caches L2 hits. My 45 - * gut feeling is this will vary by board in value. For a board 46 - * with separate L2 cache it probably depends also on the RSS, and 47 - * for a board with shared L2 cache it ought to decay fast as other 48 - * processes are run. 49 - */ 50 - 51 - #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ 52 - 53 19 #define raw_smp_processor_id() (S390_lowcore.cpu_nr) 54 - #define cpu_logical_map(cpu) (cpu) 55 20 56 21 extern int __cpu_disable (void); 57 22 extern void __cpu_die (unsigned int cpu); ··· 29 64 extern void arch_send_call_function_single_ipi(int cpu); 30 65 extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); 31 66 32 - #endif 67 + extern union save_area *zfcpdump_save_areas[NR_CPUS + 1]; 68 + 69 + #endif /* CONFIG_SMP */ 33 70 34 71 #ifdef CONFIG_HOTPLUG_CPU 35 72 extern int smp_rescan_cpus(void); ··· 39 72 static inline int smp_rescan_cpus(void) { return 0; } 40 73 #endif 41 74 42 - extern union save_area *zfcpdump_save_areas[NR_CPUS + 1]; 43 - #endif 75 + #endif /* __ASM_SMP_H */
+3 -18
arch/s390/include/asm/sockios.h
··· 1 - /* 2 - * include/asm-s390/sockios.h 3 - * 4 - * S390 version 5 - * 6 - * Derived from "include/asm-i386/sockios.h" 7 - */ 1 + #ifndef _ASM_S390_SOCKIOS_H 2 + #define _ASM_S390_SOCKIOS_H 8 3 9 - #ifndef __ARCH_S390_SOCKIOS__ 10 - #define __ARCH_S390_SOCKIOS__ 11 - 12 - /* Socket-level I/O control calls. */ 13 - #define FIOSETOWN 0x8901 14 - #define SIOCSPGRP 0x8902 15 - #define FIOGETOWN 0x8903 16 - #define SIOCGPGRP 0x8904 17 - #define SIOCATMARK 0x8905 18 - #define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ 19 - #define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ 4 + #include <asm-generic/sockios.h> 20 5 21 6 #endif
+3 -203
arch/s390/include/asm/termbits.h
··· 1 - /* 2 - * include/asm-s390/termbits.h 3 - * 4 - * S390 version 5 - * 6 - * Derived from "include/asm-i386/termbits.h" 7 - */ 1 + #ifndef _ASM_S390_TERMBITS_H 2 + #define _ASM_S390_TERMBITS_H 8 3 9 - #ifndef __ARCH_S390_TERMBITS_H__ 10 - #define __ARCH_S390_TERMBITS_H__ 11 - 12 - #include <linux/posix_types.h> 13 - 14 - typedef unsigned char cc_t; 15 - typedef unsigned int speed_t; 16 - typedef unsigned int tcflag_t; 17 - 18 - #define NCCS 19 19 - struct termios { 20 - tcflag_t c_iflag; /* input mode flags */ 21 - tcflag_t c_oflag; /* output mode flags */ 22 - tcflag_t c_cflag; /* control mode flags */ 23 - tcflag_t c_lflag; /* local mode flags */ 24 - cc_t c_line; /* line discipline */ 25 - cc_t c_cc[NCCS]; /* control characters */ 26 - }; 27 - 28 - struct termios2 { 29 - tcflag_t c_iflag; /* input mode flags */ 30 - tcflag_t c_oflag; /* output mode flags */ 31 - tcflag_t c_cflag; /* control mode flags */ 32 - tcflag_t c_lflag; /* local mode flags */ 33 - cc_t c_line; /* line discipline */ 34 - cc_t c_cc[NCCS]; /* control characters */ 35 - speed_t c_ispeed; /* input speed */ 36 - speed_t c_ospeed; /* output speed */ 37 - }; 38 - 39 - struct ktermios { 40 - tcflag_t c_iflag; /* input mode flags */ 41 - tcflag_t c_oflag; /* output mode flags */ 42 - tcflag_t c_cflag; /* control mode flags */ 43 - tcflag_t c_lflag; /* local mode flags */ 44 - cc_t c_line; /* line discipline */ 45 - cc_t c_cc[NCCS]; /* control characters */ 46 - speed_t c_ispeed; /* input speed */ 47 - speed_t c_ospeed; /* output speed */ 48 - }; 49 - 50 - /* c_cc characters */ 51 - #define VINTR 0 52 - #define VQUIT 1 53 - #define VERASE 2 54 - #define VKILL 3 55 - #define VEOF 4 56 - #define VTIME 5 57 - #define VMIN 6 58 - #define VSWTC 7 59 - #define VSTART 8 60 - #define VSTOP 9 61 - #define VSUSP 10 62 - #define VEOL 11 63 - #define VREPRINT 12 64 - #define VDISCARD 13 65 - #define VWERASE 14 66 - #define VLNEXT 15 67 - #define VEOL2 16 68 - 69 - /* c_iflag bits */ 70 - #define IGNBRK 0000001 71 - #define BRKINT 0000002 72 - #define IGNPAR 0000004 73 - #define PARMRK 0000010 74 - #define INPCK 0000020 75 - #define ISTRIP 0000040 76 - #define INLCR 0000100 77 - #define IGNCR 0000200 78 - #define ICRNL 0000400 79 - #define IUCLC 0001000 80 - #define IXON 0002000 81 - #define IXANY 0004000 82 - #define IXOFF 0010000 83 - #define IMAXBEL 0020000 84 - #define IUTF8 0040000 85 - 86 - /* c_oflag bits */ 87 - #define OPOST 0000001 88 - #define OLCUC 0000002 89 - #define ONLCR 0000004 90 - #define OCRNL 0000010 91 - #define ONOCR 0000020 92 - #define ONLRET 0000040 93 - #define OFILL 0000100 94 - #define OFDEL 0000200 95 - #define NLDLY 0000400 96 - #define NL0 0000000 97 - #define NL1 0000400 98 - #define CRDLY 0003000 99 - #define CR0 0000000 100 - #define CR1 0001000 101 - #define CR2 0002000 102 - #define CR3 0003000 103 - #define TABDLY 0014000 104 - #define TAB0 0000000 105 - #define TAB1 0004000 106 - #define TAB2 0010000 107 - #define TAB3 0014000 108 - #define XTABS 0014000 109 - #define BSDLY 0020000 110 - #define BS0 0000000 111 - #define BS1 0020000 112 - #define VTDLY 0040000 113 - #define VT0 0000000 114 - #define VT1 0040000 115 - #define FFDLY 0100000 116 - #define FF0 0000000 117 - #define FF1 0100000 118 - 119 - /* c_cflag bit meaning */ 120 - #define CBAUD 0010017 121 - #define B0 0000000 /* hang up */ 122 - #define B50 0000001 123 - #define B75 0000002 124 - #define B110 0000003 125 - #define B134 0000004 126 - #define B150 0000005 127 - #define B200 0000006 128 - #define B300 0000007 129 - #define B600 0000010 130 - #define B1200 0000011 131 - #define B1800 0000012 132 - #define B2400 0000013 133 - #define B4800 0000014 134 - #define B9600 0000015 135 - #define B19200 0000016 136 - #define B38400 0000017 137 - #define EXTA B19200 138 - #define EXTB B38400 139 - #define CSIZE 0000060 140 - #define CS5 0000000 141 - #define CS6 0000020 142 - #define CS7 0000040 143 - #define CS8 0000060 144 - #define CSTOPB 0000100 145 - #define CREAD 0000200 146 - #define PARENB 0000400 147 - #define PARODD 0001000 148 - #define HUPCL 0002000 149 - #define CLOCAL 0004000 150 - #define CBAUDEX 0010000 151 - #define BOTHER 0010000 152 - #define B57600 0010001 153 - #define B115200 0010002 154 - #define B230400 0010003 155 - #define B460800 0010004 156 - #define B500000 0010005 157 - #define B576000 0010006 158 - #define B921600 0010007 159 - #define B1000000 0010010 160 - #define B1152000 0010011 161 - #define B1500000 0010012 162 - #define B2000000 0010013 163 - #define B2500000 0010014 164 - #define B3000000 0010015 165 - #define B3500000 0010016 166 - #define B4000000 0010017 167 - #define CIBAUD 002003600000 /* input baud rate */ 168 - #define CMSPAR 010000000000 /* mark or space (stick) parity */ 169 - #define CRTSCTS 020000000000 /* flow control */ 170 - 171 - #define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ 172 - 173 - /* c_lflag bits */ 174 - #define ISIG 0000001 175 - #define ICANON 0000002 176 - #define XCASE 0000004 177 - #define ECHO 0000010 178 - #define ECHOE 0000020 179 - #define ECHOK 0000040 180 - #define ECHONL 0000100 181 - #define NOFLSH 0000200 182 - #define TOSTOP 0000400 183 - #define ECHOCTL 0001000 184 - #define ECHOPRT 0002000 185 - #define ECHOKE 0004000 186 - #define FLUSHO 0010000 187 - #define PENDIN 0040000 188 - #define IEXTEN 0100000 189 - 190 - /* tcflow() and TCXONC use these */ 191 - #define TCOOFF 0 192 - #define TCOON 1 193 - #define TCIOFF 2 194 - #define TCION 3 195 - 196 - /* tcflush() and TCFLSH use these */ 197 - #define TCIFLUSH 0 198 - #define TCOFLUSH 1 199 - #define TCIOFLUSH 2 200 - 201 - /* tcsetattr uses these */ 202 - #define TCSANOW 0 203 - #define TCSADRAIN 1 204 - #define TCSAFLUSH 2 4 + #include <asm-generic/termbits.h> 205 5 206 6 #endif
-23
arch/s390/include/asm/todclk.h
··· 1 - /* 2 - * File...........: linux/include/asm/todclk.h 3 - * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> 4 - * Bugreports.to..: <Linux390@de.ibm.com> 5 - * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 6 - * 7 - * History of changes (starts July 2000) 8 - */ 9 - 10 - #ifndef __ASM_TODCLK_H 11 - #define __ASM_TODCLK_H 12 - 13 - #ifdef __KERNEL__ 14 - 15 - #define TOD_uSEC (0x1000ULL) 16 - #define TOD_mSEC (1000 * TOD_uSEC) 17 - #define TOD_SEC (1000 * TOD_mSEC) 18 - #define TOD_MIN (60 * TOD_SEC) 19 - #define TOD_HOUR (60 * TOD_MIN) 20 - 21 - #endif 22 - 23 - #endif
+2
arch/s390/include/asm/uaccess.h
··· 93 93 extern struct uaccess_ops uaccess_mvcos_switch; 94 94 extern struct uaccess_ops uaccess_pt; 95 95 96 + extern int __handle_fault(unsigned long, unsigned long, int); 97 + 96 98 static inline int __put_user_fn(size_t size, void __user *ptr, void *x) 97 99 { 98 100 size = uaccess.copy_to_user_small(size, ptr, x);
+1
arch/s390/kernel/Makefile
··· 44 44 obj-$(CONFIG_FUNCTION_TRACER) += $(if $(CONFIG_64BIT),mcount64.o,mcount.o) 45 45 obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o 46 46 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o 47 + obj-$(CONFIG_FTRACE_SYSCALLS) += ftrace.o 47 48 48 49 # Kexec part 49 50 S390_KEXEC_OBJS := machine_kexec.o crash.o
-6
arch/s390/kernel/compat_linux.c
··· 31 31 #include <linux/shm.h> 32 32 #include <linux/slab.h> 33 33 #include <linux/uio.h> 34 - #include <linux/nfs_fs.h> 35 34 #include <linux/quota.h> 36 35 #include <linux/module.h> 37 - #include <linux/sunrpc/svc.h> 38 - #include <linux/nfsd/nfsd.h> 39 - #include <linux/nfsd/cache.h> 40 - #include <linux/nfsd/xdr.h> 41 - #include <linux/nfsd/syscall.h> 42 36 #include <linux/poll.h> 43 37 #include <linux/personality.h> 44 38 #include <linux/stat.h>
-4
arch/s390/kernel/compat_linux.h
··· 4 4 #include <linux/compat.h> 5 5 #include <linux/socket.h> 6 6 #include <linux/syscalls.h> 7 - #include <linux/nfs_fs.h> 8 - #include <linux/sunrpc/svc.h> 9 - #include <linux/nfsd/nfsd.h> 10 - #include <linux/nfsd/export.h> 11 7 12 8 /* Macro that masks the high order bit of an 32 bit pointer and converts it*/ 13 9 /* to a 64 bit pointer */
+3
arch/s390/kernel/head64.S
··· 83 83 slr %r0,%r0 # set cpuid to zero 84 84 sigp %r1,%r0,0x12 # switch to esame mode 85 85 sam64 # switch to 64 bit mode 86 + llgfr %r13,%r13 # clear high-order half of base reg 87 + lmh %r0,%r15,.Lzero64-.LPG1(%r13) # clear high-order half 86 88 lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers 87 89 lg %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area 88 90 # move IPL device to lowcore ··· 129 127 .L4malign:.quad 0xffffffffffc00000 130 128 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 131 129 .Lnop: .long 0x07000700 130 + .Lzero64:.fill 16,4,0x0 132 131 #ifdef CONFIG_ZFCPDUMP 133 132 .Lcurrent_cpu: 134 133 .long 0x0
+20 -16
arch/s390/kernel/setup.c
··· 305 305 } 306 306 early_param("mem", early_parse_mem); 307 307 308 - #ifdef CONFIG_S390_SWITCH_AMODE 309 - unsigned int switch_amode = 0; 310 - EXPORT_SYMBOL_GPL(switch_amode); 308 + unsigned int user_mode = HOME_SPACE_MODE; 309 + EXPORT_SYMBOL_GPL(user_mode); 311 310 312 311 static int set_amode_and_uaccess(unsigned long user_amode, 313 312 unsigned long user32_amode) ··· 339 340 */ 340 341 static int __init early_parse_switch_amode(char *p) 341 342 { 342 - switch_amode = 1; 343 + if (user_mode != SECONDARY_SPACE_MODE) 344 + user_mode = PRIMARY_SPACE_MODE; 343 345 return 0; 344 346 } 345 347 early_param("switch_amode", early_parse_switch_amode); 346 348 347 - #else /* CONFIG_S390_SWITCH_AMODE */ 348 - static inline int set_amode_and_uaccess(unsigned long user_amode, 349 - unsigned long user32_amode) 349 + static int __init early_parse_user_mode(char *p) 350 350 { 351 + if (p && strcmp(p, "primary") == 0) 352 + user_mode = PRIMARY_SPACE_MODE; 353 + #ifdef CONFIG_S390_EXEC_PROTECT 354 + else if (p && strcmp(p, "secondary") == 0) 355 + user_mode = SECONDARY_SPACE_MODE; 356 + #endif 357 + else if (!p || strcmp(p, "home") == 0) 358 + user_mode = HOME_SPACE_MODE; 359 + else 360 + return 1; 351 361 return 0; 352 362 } 353 - #endif /* CONFIG_S390_SWITCH_AMODE */ 363 + early_param("user_mode", early_parse_user_mode); 354 364 355 365 #ifdef CONFIG_S390_EXEC_PROTECT 356 - unsigned int s390_noexec = 0; 357 - EXPORT_SYMBOL_GPL(s390_noexec); 358 - 359 366 /* 360 367 * Enable execute protection? 361 368 */ ··· 369 364 { 370 365 if (!strncmp(p, "off", 3)) 371 366 return 0; 372 - switch_amode = 1; 373 - s390_noexec = 1; 367 + user_mode = SECONDARY_SPACE_MODE; 374 368 return 0; 375 369 } 376 370 early_param("noexec", early_parse_noexec); ··· 377 373 378 374 static void setup_addressing_mode(void) 379 375 { 380 - if (s390_noexec) { 376 + if (user_mode == SECONDARY_SPACE_MODE) { 381 377 if (set_amode_and_uaccess(PSW_ASC_SECONDARY, 382 378 PSW32_ASC_SECONDARY)) 383 379 pr_info("Execute protection active, " ··· 385 381 else 386 382 pr_info("Execute protection active, " 387 383 "mvcos not available\n"); 388 - } else if (switch_amode) { 384 + } else if (user_mode == PRIMARY_SPACE_MODE) { 389 385 if (set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY)) 390 386 pr_info("Address spaces switched, " 391 387 "mvcos available\n"); ··· 415 411 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; 416 412 lc->restart_psw.addr = 417 413 PSW_ADDR_AMODE | (unsigned long) restart_int_handler; 418 - if (switch_amode) 414 + if (user_mode != HOME_SPACE_MODE) 419 415 lc->restart_psw.mask |= PSW_ASC_HOME; 420 416 lc->external_new_psw.mask = psw_kernel_bits; 421 417 lc->external_new_psw.addr =
+2 -2
arch/s390/kernel/time.c
··· 335 335 sw0 = atomic_read(sw_ptr); 336 336 *clock = get_clock(); 337 337 sw1 = atomic_read(sw_ptr); 338 - put_cpu_var(clock_sync_sync); 338 + put_cpu_var(clock_sync_word); 339 339 if (sw0 == sw1 && (sw0 & 0x80000000U)) 340 340 /* Success: time is in sync. */ 341 341 return 0; ··· 385 385 386 386 sw_ptr = &get_cpu_var(clock_sync_word); 387 387 rc = (atomic_read(sw_ptr) & 0x80000000U) != 0; 388 - put_cpu_var(clock_sync_sync); 388 + put_cpu_var(clock_sync_word); 389 389 return rc; 390 390 } 391 391
+5 -4
arch/s390/kernel/vdso.c
··· 86 86 unsigned int facility_list; 87 87 88 88 facility_list = stfl(); 89 - vd->ectg_available = switch_amode && (facility_list & 1); 89 + vd->ectg_available = 90 + user_mode != HOME_SPACE_MODE && (facility_list & 1); 90 91 } 91 92 92 93 #ifdef CONFIG_64BIT ··· 115 114 116 115 lowcore->vdso_per_cpu_data = __LC_PASTE; 117 116 118 - if (!switch_amode || !vdso_enabled) 117 + if (user_mode == HOME_SPACE_MODE || !vdso_enabled) 119 118 return 0; 120 119 121 120 segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER); ··· 161 160 unsigned long segment_table, page_table, page_frame; 162 161 u32 *psal, *aste; 163 162 164 - if (!switch_amode || !vdso_enabled) 163 + if (user_mode == HOME_SPACE_MODE || !vdso_enabled) 165 164 return; 166 165 167 166 psal = (u32 *)(addr_t) lowcore->paste[4]; ··· 185 184 186 185 static void vdso_init_cr5(void) 187 186 { 188 - if (switch_amode && vdso_enabled) 187 + if (user_mode != HOME_SPACE_MODE && vdso_enabled) 189 188 on_each_cpu(__vdso_init_cr5, NULL, 1); 190 189 } 191 190 #endif /* CONFIG_64BIT */
-1
arch/s390/kvm/Kconfig
··· 20 20 depends on HAVE_KVM && EXPERIMENTAL 21 21 select PREEMPT_NOTIFIERS 22 22 select ANON_INODES 23 - select S390_SWITCH_AMODE 24 23 ---help--- 25 24 Support hosting paravirtualized guest machines using the SIE 26 25 virtualization capability on the mainframe. This should work
-4
arch/s390/lib/uaccess_mvcos.c
··· 162 162 return size; 163 163 } 164 164 165 - #ifdef CONFIG_S390_SWITCH_AMODE 166 165 static size_t strnlen_user_mvcos(size_t count, const char __user *src) 167 166 { 168 167 char buf[256]; ··· 199 200 } while ((len_str == len) && (done < count)); 200 201 return done; 201 202 } 202 - #endif /* CONFIG_S390_SWITCH_AMODE */ 203 203 204 204 struct uaccess_ops uaccess_mvcos = { 205 205 .copy_from_user = copy_from_user_mvcos_check, ··· 213 215 .futex_atomic_cmpxchg = futex_atomic_cmpxchg_std, 214 216 }; 215 217 216 - #ifdef CONFIG_S390_SWITCH_AMODE 217 218 struct uaccess_ops uaccess_mvcos_switch = { 218 219 .copy_from_user = copy_from_user_mvcos, 219 220 .copy_from_user_small = copy_from_user_mvcos, ··· 225 228 .futex_atomic_op = futex_atomic_op_pt, 226 229 .futex_atomic_cmpxchg = futex_atomic_cmpxchg_pt, 227 230 }; 228 - #endif
+51 -96
arch/s390/lib/uaccess_pt.c
··· 23 23 24 24 pgd = pgd_offset(mm, addr); 25 25 if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) 26 - return NULL; 26 + return (pte_t *) 0x3a; 27 27 28 28 pud = pud_offset(pgd, addr); 29 29 if (pud_none(*pud) || unlikely(pud_bad(*pud))) 30 - return NULL; 30 + return (pte_t *) 0x3b; 31 31 32 32 pmd = pmd_offset(pud, addr); 33 33 if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) 34 - return NULL; 34 + return (pte_t *) 0x10; 35 35 36 36 return pte_offset_map(pmd, addr); 37 37 } 38 38 39 - static int __handle_fault(struct mm_struct *mm, unsigned long address, 40 - int write_access) 41 - { 42 - struct vm_area_struct *vma; 43 - int ret = -EFAULT; 44 - int fault; 45 - 46 - if (in_atomic()) 47 - return ret; 48 - down_read(&mm->mmap_sem); 49 - vma = find_vma(mm, address); 50 - if (unlikely(!vma)) 51 - goto out; 52 - if (unlikely(vma->vm_start > address)) { 53 - if (!(vma->vm_flags & VM_GROWSDOWN)) 54 - goto out; 55 - if (expand_stack(vma, address)) 56 - goto out; 57 - } 58 - 59 - if (!write_access) { 60 - /* page not present, check vm flags */ 61 - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) 62 - goto out; 63 - } else { 64 - if (!(vma->vm_flags & VM_WRITE)) 65 - goto out; 66 - } 67 - 68 - survive: 69 - fault = handle_mm_fault(mm, vma, address, write_access ? FAULT_FLAG_WRITE : 0); 70 - if (unlikely(fault & VM_FAULT_ERROR)) { 71 - if (fault & VM_FAULT_OOM) 72 - goto out_of_memory; 73 - else if (fault & VM_FAULT_SIGBUS) 74 - goto out_sigbus; 75 - BUG(); 76 - } 77 - if (fault & VM_FAULT_MAJOR) 78 - current->maj_flt++; 79 - else 80 - current->min_flt++; 81 - ret = 0; 82 - out: 83 - up_read(&mm->mmap_sem); 84 - return ret; 85 - 86 - out_of_memory: 87 - up_read(&mm->mmap_sem); 88 - if (is_global_init(current)) { 89 - yield(); 90 - down_read(&mm->mmap_sem); 91 - goto survive; 92 - } 93 - printk("VM: killing process %s\n", current->comm); 94 - return ret; 95 - 96 - out_sigbus: 97 - up_read(&mm->mmap_sem); 98 - current->thread.prot_addr = address; 99 - current->thread.trap_no = 0x11; 100 - force_sig(SIGBUS, current); 101 - return ret; 102 - } 103 - 104 - static size_t __user_copy_pt(unsigned long uaddr, void *kptr, 105 - size_t n, int write_user) 39 + static __always_inline size_t __user_copy_pt(unsigned long uaddr, void *kptr, 40 + size_t n, int write_user) 106 41 { 107 42 struct mm_struct *mm = current->mm; 108 43 unsigned long offset, pfn, done, size; ··· 49 114 spin_lock(&mm->page_table_lock); 50 115 do { 51 116 pte = follow_table(mm, uaddr); 52 - if (!pte || !pte_present(*pte) || 53 - (write_user && !pte_write(*pte))) 117 + if ((unsigned long) pte < 0x1000) 54 118 goto fault; 119 + if (!pte_present(*pte)) { 120 + pte = (pte_t *) 0x11; 121 + goto fault; 122 + } else if (write_user && !pte_write(*pte)) { 123 + pte = (pte_t *) 0x04; 124 + goto fault; 125 + } 55 126 56 127 pfn = pte_pfn(*pte); 57 - 58 128 offset = uaddr & (PAGE_SIZE - 1); 59 129 size = min(n - done, PAGE_SIZE - offset); 60 130 if (write_user) { ··· 77 137 return n - done; 78 138 fault: 79 139 spin_unlock(&mm->page_table_lock); 80 - if (__handle_fault(mm, uaddr, write_user)) 140 + if (__handle_fault(uaddr, (unsigned long) pte, write_user)) 81 141 return n - done; 82 142 goto retry; 83 143 } ··· 86 146 * Do DAT for user address by page table walk, return kernel address. 87 147 * This function needs to be called with current->mm->page_table_lock held. 88 148 */ 89 - static unsigned long __dat_user_addr(unsigned long uaddr) 149 + static __always_inline unsigned long __dat_user_addr(unsigned long uaddr) 90 150 { 91 151 struct mm_struct *mm = current->mm; 92 - unsigned long pfn, ret; 152 + unsigned long pfn; 93 153 pte_t *pte; 94 154 int rc; 95 155 96 - ret = 0; 97 156 retry: 98 157 pte = follow_table(mm, uaddr); 99 - if (!pte || !pte_present(*pte)) 158 + if ((unsigned long) pte < 0x1000) 100 159 goto fault; 160 + if (!pte_present(*pte)) { 161 + pte = (pte_t *) 0x11; 162 + goto fault; 163 + } 101 164 102 165 pfn = pte_pfn(*pte); 103 - ret = (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1)); 104 - out: 105 - return ret; 166 + return (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1)); 106 167 fault: 107 168 spin_unlock(&mm->page_table_lock); 108 - rc = __handle_fault(mm, uaddr, 0); 169 + rc = __handle_fault(uaddr, (unsigned long) pte, 0); 109 170 spin_lock(&mm->page_table_lock); 110 - if (rc) 111 - goto out; 112 - goto retry; 171 + if (!rc) 172 + goto retry; 173 + return 0; 113 174 } 114 175 115 176 size_t copy_from_user_pt(size_t n, const void __user *from, void *to) ··· 175 234 spin_lock(&mm->page_table_lock); 176 235 do { 177 236 pte = follow_table(mm, uaddr); 178 - if (!pte || !pte_present(*pte)) 237 + if ((unsigned long) pte < 0x1000) 179 238 goto fault; 239 + if (!pte_present(*pte)) { 240 + pte = (pte_t *) 0x11; 241 + goto fault; 242 + } 180 243 181 244 pfn = pte_pfn(*pte); 182 245 offset = uaddr & (PAGE_SIZE-1); ··· 194 249 return done + 1; 195 250 fault: 196 251 spin_unlock(&mm->page_table_lock); 197 - if (__handle_fault(mm, uaddr, 0)) { 252 + if (__handle_fault(uaddr, (unsigned long) pte, 0)) 198 253 return 0; 199 - } 200 254 goto retry; 201 255 } 202 256 ··· 228 284 { 229 285 struct mm_struct *mm = current->mm; 230 286 unsigned long offset_from, offset_to, offset_max, pfn_from, pfn_to, 231 - uaddr, done, size; 287 + uaddr, done, size, error_code; 232 288 unsigned long uaddr_from = (unsigned long) from; 233 289 unsigned long uaddr_to = (unsigned long) to; 234 290 pte_t *pte_from, *pte_to; ··· 242 298 retry: 243 299 spin_lock(&mm->page_table_lock); 244 300 do { 301 + write_user = 0; 302 + uaddr = uaddr_from; 245 303 pte_from = follow_table(mm, uaddr_from); 246 - if (!pte_from || !pte_present(*pte_from)) { 247 - uaddr = uaddr_from; 248 - write_user = 0; 304 + error_code = (unsigned long) pte_from; 305 + if (error_code < 0x1000) 306 + goto fault; 307 + if (!pte_present(*pte_from)) { 308 + error_code = 0x11; 249 309 goto fault; 250 310 } 251 311 312 + write_user = 1; 313 + uaddr = uaddr_to; 252 314 pte_to = follow_table(mm, uaddr_to); 253 - if (!pte_to || !pte_present(*pte_to) || !pte_write(*pte_to)) { 254 - uaddr = uaddr_to; 255 - write_user = 1; 315 + error_code = (unsigned long) pte_to; 316 + if (error_code < 0x1000) 317 + goto fault; 318 + if (!pte_present(*pte_to)) { 319 + error_code = 0x11; 320 + goto fault; 321 + } else if (!pte_write(*pte_to)) { 322 + error_code = 0x04; 256 323 goto fault; 257 324 } 258 325 ··· 284 329 return n - done; 285 330 fault: 286 331 spin_unlock(&mm->page_table_lock); 287 - if (__handle_fault(mm, uaddr, write_user)) 332 + if (__handle_fault(uaddr, error_code, write_user)) 288 333 return n - done; 289 334 goto retry; 290 335 }
+50 -11
arch/s390/mm/cmm.c
··· 18 18 #include <linux/swap.h> 19 19 #include <linux/kthread.h> 20 20 #include <linux/oom.h> 21 + #include <linux/suspend.h> 21 22 22 23 #include <asm/pgalloc.h> 23 24 #include <asm/uaccess.h> ··· 45 44 static volatile long cmm_timed_pages_target; 46 45 static long cmm_timeout_pages; 47 46 static long cmm_timeout_seconds; 47 + static int cmm_suspended; 48 48 49 49 static struct cmm_page_array *cmm_page_list; 50 50 static struct cmm_page_array *cmm_timed_page_list; ··· 149 147 150 148 while (1) { 151 149 rc = wait_event_interruptible(cmm_thread_wait, 152 - (cmm_pages != cmm_pages_target || 153 - cmm_timed_pages != cmm_timed_pages_target || 154 - kthread_should_stop())); 150 + (!cmm_suspended && (cmm_pages != cmm_pages_target || 151 + cmm_timed_pages != cmm_timed_pages_target)) || 152 + kthread_should_stop()); 155 153 if (kthread_should_stop() || rc == -ERESTARTSYS) { 156 154 cmm_pages_target = cmm_pages; 157 155 cmm_timed_pages_target = cmm_timed_pages; ··· 412 410 413 411 static struct ctl_table_header *cmm_sysctl_header; 414 412 413 + static int cmm_suspend(void) 414 + { 415 + cmm_suspended = 1; 416 + cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list); 417 + cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list); 418 + return 0; 419 + } 420 + 421 + static int cmm_resume(void) 422 + { 423 + cmm_suspended = 0; 424 + cmm_kick_thread(); 425 + return 0; 426 + } 427 + 428 + static int cmm_power_event(struct notifier_block *this, 429 + unsigned long event, void *ptr) 430 + { 431 + switch (event) { 432 + case PM_POST_HIBERNATION: 433 + return cmm_resume(); 434 + case PM_HIBERNATION_PREPARE: 435 + return cmm_suspend(); 436 + default: 437 + return NOTIFY_DONE; 438 + } 439 + } 440 + 441 + static struct notifier_block cmm_power_notifier = { 442 + .notifier_call = cmm_power_event, 443 + }; 444 + 415 445 static int 416 446 cmm_init (void) 417 447 { ··· 452 418 #ifdef CONFIG_CMM_PROC 453 419 cmm_sysctl_header = register_sysctl_table(cmm_dir_table); 454 420 if (!cmm_sysctl_header) 455 - goto out; 421 + goto out_sysctl; 456 422 #endif 457 423 #ifdef CONFIG_CMM_IUCV 458 424 rc = smsg_register_callback(SMSG_PREFIX, cmm_smsg_target); ··· 462 428 rc = register_oom_notifier(&cmm_oom_nb); 463 429 if (rc < 0) 464 430 goto out_oom_notify; 431 + rc = register_pm_notifier(&cmm_power_notifier); 432 + if (rc) 433 + goto out_pm; 465 434 init_waitqueue_head(&cmm_thread_wait); 466 435 init_timer(&cmm_timer); 467 436 cmm_thread_ptr = kthread_run(cmm_thread, NULL, "cmmthread"); 468 437 rc = IS_ERR(cmm_thread_ptr) ? PTR_ERR(cmm_thread_ptr) : 0; 469 - if (!rc) 470 - goto out; 471 - /* 472 - * kthread_create failed. undo all the stuff from above again. 473 - */ 474 - unregister_oom_notifier(&cmm_oom_nb); 438 + if (rc) 439 + goto out_kthread; 440 + return 0; 475 441 442 + out_kthread: 443 + unregister_pm_notifier(&cmm_power_notifier); 444 + out_pm: 445 + unregister_oom_notifier(&cmm_oom_nb); 476 446 out_oom_notify: 477 447 #ifdef CONFIG_CMM_IUCV 478 448 smsg_unregister_callback(SMSG_PREFIX, cmm_smsg_target); ··· 484 446 #endif 485 447 #ifdef CONFIG_CMM_PROC 486 448 unregister_sysctl_table(cmm_sysctl_header); 449 + out_sysctl: 487 450 #endif 488 - out: 489 451 return rc; 490 452 } 491 453 ··· 493 455 cmm_exit(void) 494 456 { 495 457 kthread_stop(cmm_thread_ptr); 458 + unregister_pm_notifier(&cmm_power_notifier); 496 459 unregister_oom_notifier(&cmm_oom_nb); 497 460 cmm_free_pages(cmm_pages, &cmm_pages, &cmm_page_list); 498 461 cmm_free_pages(cmm_timed_pages, &cmm_timed_pages, &cmm_timed_page_list);
+191 -187
arch/s390/mm/fault.c
··· 34 34 #include <asm/pgtable.h> 35 35 #include <asm/s390_ext.h> 36 36 #include <asm/mmu_context.h> 37 + #include <asm/compat.h> 37 38 #include "../kernel/entry.h" 38 39 39 40 #ifndef CONFIG_64BIT 40 41 #define __FAIL_ADDR_MASK 0x7ffff000 41 - #define __FIXUP_MASK 0x7fffffff 42 42 #define __SUBCODE_MASK 0x0200 43 43 #define __PF_RES_FIELD 0ULL 44 44 #else /* CONFIG_64BIT */ 45 45 #define __FAIL_ADDR_MASK -4096L 46 - #define __FIXUP_MASK ~0L 47 46 #define __SUBCODE_MASK 0x0600 48 47 #define __PF_RES_FIELD 0x8000000000000000ULL 49 48 #endif /* CONFIG_64BIT */ ··· 51 52 extern int sysctl_userprocess_debug; 52 53 #endif 53 54 54 - #ifdef CONFIG_KPROBES 55 - static inline int notify_page_fault(struct pt_regs *regs, long err) 55 + #define VM_FAULT_BADCONTEXT 0x010000 56 + #define VM_FAULT_BADMAP 0x020000 57 + #define VM_FAULT_BADACCESS 0x040000 58 + 59 + static inline int notify_page_fault(struct pt_regs *regs) 56 60 { 57 61 int ret = 0; 58 62 63 + #ifdef CONFIG_KPROBES 59 64 /* kprobe_running() needs smp_processor_id() */ 60 65 if (!user_mode(regs)) { 61 66 preempt_disable(); ··· 67 64 ret = 1; 68 65 preempt_enable(); 69 66 } 70 - 67 + #endif 71 68 return ret; 72 69 } 73 - #else 74 - static inline int notify_page_fault(struct pt_regs *regs, long err) 75 - { 76 - return 0; 77 - } 78 - #endif 79 70 80 71 81 72 /* ··· 97 100 98 101 /* 99 102 * Returns the address space associated with the fault. 100 - * Returns 0 for kernel space, 1 for user space and 101 - * 2 for code execution in user space with noexec=on. 103 + * Returns 0 for kernel space and 1 for user space. 102 104 */ 103 - static inline int check_space(struct task_struct *tsk) 105 + static inline int user_space_fault(unsigned long trans_exc_code) 104 106 { 105 107 /* 106 - * The lowest two bits of S390_lowcore.trans_exc_code 107 - * indicate which paging table was used. 108 + * The lowest two bits of the translation exception 109 + * identification indicate which paging table was used. 108 110 */ 109 - int desc = S390_lowcore.trans_exc_code & 3; 110 - 111 - if (desc == 3) /* Home Segment Table Descriptor */ 112 - return switch_amode == 0; 113 - if (desc == 2) /* Secondary Segment Table Descriptor */ 114 - return tsk->thread.mm_segment.ar4; 115 - #ifdef CONFIG_S390_SWITCH_AMODE 116 - if (unlikely(desc == 1)) { /* STD determined via access register */ 117 - /* %a0 always indicates primary space. */ 118 - if (S390_lowcore.exc_access_id != 0) { 119 - save_access_regs(tsk->thread.acrs); 120 - /* 121 - * An alet of 0 indicates primary space. 122 - * An alet of 1 indicates secondary space. 123 - * Any other alet values generate an 124 - * alen-translation exception. 125 - */ 126 - if (tsk->thread.acrs[S390_lowcore.exc_access_id]) 127 - return tsk->thread.mm_segment.ar4; 128 - } 129 - } 130 - #endif 131 - /* Primary Segment Table Descriptor */ 132 - return switch_amode << s390_noexec; 111 + trans_exc_code &= 3; 112 + if (trans_exc_code == 2) 113 + /* Access via secondary space, set_fs setting decides */ 114 + return current->thread.mm_segment.ar4; 115 + if (user_mode == HOME_SPACE_MODE) 116 + /* User space if the access has been done via home space. */ 117 + return trans_exc_code == 3; 118 + /* 119 + * If the user space is not the home space the kernel runs in home 120 + * space. Access via secondary space has already been covered, 121 + * access via primary space or access register is from user space 122 + * and access via home space is from the kernel. 123 + */ 124 + return trans_exc_code != 3; 133 125 } 134 126 135 127 /* 136 128 * Send SIGSEGV to task. This is an external routine 137 129 * to keep the stack usage of do_page_fault small. 138 130 */ 139 - static void do_sigsegv(struct pt_regs *regs, unsigned long error_code, 140 - int si_code, unsigned long address) 131 + static noinline void do_sigsegv(struct pt_regs *regs, long int_code, 132 + int si_code, unsigned long trans_exc_code) 141 133 { 142 134 struct siginfo si; 135 + unsigned long address; 143 136 137 + address = trans_exc_code & __FAIL_ADDR_MASK; 138 + current->thread.prot_addr = address; 139 + current->thread.trap_no = int_code; 144 140 #if defined(CONFIG_SYSCTL) || defined(CONFIG_PROCESS_DEBUG) 145 141 #if defined(CONFIG_SYSCTL) 146 142 if (sysctl_userprocess_debug) 147 143 #endif 148 144 { 149 145 printk("User process fault: interruption code 0x%lX\n", 150 - error_code); 146 + int_code); 151 147 printk("failing address: %lX\n", address); 152 148 show_regs(regs); 153 149 } ··· 151 161 force_sig_info(SIGSEGV, &si, current); 152 162 } 153 163 154 - static void do_no_context(struct pt_regs *regs, unsigned long error_code, 155 - unsigned long address) 164 + static noinline void do_no_context(struct pt_regs *regs, long int_code, 165 + unsigned long trans_exc_code) 156 166 { 157 167 const struct exception_table_entry *fixup; 168 + unsigned long address; 158 169 159 170 /* Are we prepared to handle this kernel fault? */ 160 - fixup = search_exception_tables(regs->psw.addr & __FIXUP_MASK); 171 + fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); 161 172 if (fixup) { 162 173 regs->psw.addr = fixup->fixup | PSW_ADDR_AMODE; 163 174 return; ··· 168 177 * Oops. The kernel tried to access some bad page. We'll have to 169 178 * terminate things with extreme prejudice. 170 179 */ 171 - if (check_space(current) == 0) 180 + address = trans_exc_code & __FAIL_ADDR_MASK; 181 + if (!user_space_fault(trans_exc_code)) 172 182 printk(KERN_ALERT "Unable to handle kernel pointer dereference" 173 183 " at virtual kernel address %p\n", (void *)address); 174 184 else 175 185 printk(KERN_ALERT "Unable to handle kernel paging request" 176 186 " at virtual user address %p\n", (void *)address); 177 187 178 - die("Oops", regs, error_code); 188 + die("Oops", regs, int_code); 179 189 do_exit(SIGKILL); 180 190 } 181 191 182 - static void do_low_address(struct pt_regs *regs, unsigned long error_code) 192 + static noinline void do_low_address(struct pt_regs *regs, long int_code, 193 + unsigned long trans_exc_code) 183 194 { 184 195 /* Low-address protection hit in kernel mode means 185 196 NULL pointer write access in kernel mode. */ 186 197 if (regs->psw.mask & PSW_MASK_PSTATE) { 187 198 /* Low-address protection hit in user mode 'cannot happen'. */ 188 - die ("Low-address protection", regs, error_code); 199 + die ("Low-address protection", regs, int_code); 189 200 do_exit(SIGKILL); 190 201 } 191 202 192 - do_no_context(regs, error_code, 0); 203 + do_no_context(regs, int_code, trans_exc_code); 193 204 } 194 205 195 - static void do_sigbus(struct pt_regs *regs, unsigned long error_code, 196 - unsigned long address) 206 + static noinline void do_sigbus(struct pt_regs *regs, long int_code, 207 + unsigned long trans_exc_code) 197 208 { 198 209 struct task_struct *tsk = current; 199 - struct mm_struct *mm = tsk->mm; 200 210 201 - up_read(&mm->mmap_sem); 202 211 /* 203 212 * Send a sigbus, regardless of whether we were in kernel 204 213 * or user mode. 205 214 */ 206 - tsk->thread.prot_addr = address; 207 - tsk->thread.trap_no = error_code; 215 + tsk->thread.prot_addr = trans_exc_code & __FAIL_ADDR_MASK; 216 + tsk->thread.trap_no = int_code; 208 217 force_sig(SIGBUS, tsk); 209 - 210 - /* Kernel mode? Handle exceptions or die */ 211 - if (!(regs->psw.mask & PSW_MASK_PSTATE)) 212 - do_no_context(regs, error_code, address); 213 218 } 214 219 215 220 #ifdef CONFIG_S390_EXEC_PROTECT 216 - static int signal_return(struct mm_struct *mm, struct pt_regs *regs, 217 - unsigned long address, unsigned long error_code) 221 + static noinline int signal_return(struct pt_regs *regs, long int_code, 222 + unsigned long trans_exc_code) 218 223 { 219 224 u16 instruction; 220 225 int rc; 221 - #ifdef CONFIG_COMPAT 222 - int compat; 223 - #endif 224 226 225 - pagefault_disable(); 226 227 rc = __get_user(instruction, (u16 __user *) regs->psw.addr); 227 - pagefault_enable(); 228 - if (rc) 229 - return -EFAULT; 230 228 231 - up_read(&mm->mmap_sem); 232 - clear_tsk_thread_flag(current, TIF_SINGLE_STEP); 233 - #ifdef CONFIG_COMPAT 234 - compat = is_compat_task(); 235 - if (compat && instruction == 0x0a77) 236 - sys32_sigreturn(); 237 - else if (compat && instruction == 0x0aad) 238 - sys32_rt_sigreturn(); 239 - else 240 - #endif 241 - if (instruction == 0x0a77) 242 - sys_sigreturn(); 243 - else if (instruction == 0x0aad) 244 - sys_rt_sigreturn(); 245 - else { 246 - current->thread.prot_addr = address; 247 - current->thread.trap_no = error_code; 248 - do_sigsegv(regs, error_code, SEGV_MAPERR, address); 249 - } 229 + if (!rc && instruction == 0x0a77) { 230 + clear_tsk_thread_flag(current, TIF_SINGLE_STEP); 231 + if (is_compat_task()) 232 + sys32_sigreturn(); 233 + else 234 + sys_sigreturn(); 235 + } else if (!rc && instruction == 0x0aad) { 236 + clear_tsk_thread_flag(current, TIF_SINGLE_STEP); 237 + if (is_compat_task()) 238 + sys32_rt_sigreturn(); 239 + else 240 + sys_rt_sigreturn(); 241 + } else 242 + do_sigsegv(regs, int_code, SEGV_MAPERR, trans_exc_code); 250 243 return 0; 251 244 } 252 245 #endif /* CONFIG_S390_EXEC_PROTECT */ 246 + 247 + static noinline void do_fault_error(struct pt_regs *regs, long int_code, 248 + unsigned long trans_exc_code, int fault) 249 + { 250 + int si_code; 251 + 252 + switch (fault) { 253 + case VM_FAULT_BADACCESS: 254 + #ifdef CONFIG_S390_EXEC_PROTECT 255 + if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY && 256 + (trans_exc_code & 3) == 0) { 257 + signal_return(regs, int_code, trans_exc_code); 258 + break; 259 + } 260 + #endif /* CONFIG_S390_EXEC_PROTECT */ 261 + case VM_FAULT_BADMAP: 262 + /* Bad memory access. Check if it is kernel or user space. */ 263 + if (regs->psw.mask & PSW_MASK_PSTATE) { 264 + /* User mode accesses just cause a SIGSEGV */ 265 + si_code = (fault == VM_FAULT_BADMAP) ? 266 + SEGV_MAPERR : SEGV_ACCERR; 267 + do_sigsegv(regs, int_code, si_code, trans_exc_code); 268 + return; 269 + } 270 + case VM_FAULT_BADCONTEXT: 271 + do_no_context(regs, int_code, trans_exc_code); 272 + break; 273 + default: /* fault & VM_FAULT_ERROR */ 274 + if (fault & VM_FAULT_OOM) 275 + pagefault_out_of_memory(); 276 + else if (fault & VM_FAULT_SIGBUS) { 277 + do_sigbus(regs, int_code, trans_exc_code); 278 + /* Kernel mode? Handle exceptions or die */ 279 + if (!(regs->psw.mask & PSW_MASK_PSTATE)) 280 + do_no_context(regs, int_code, trans_exc_code); 281 + } else 282 + BUG(); 283 + break; 284 + } 285 + } 253 286 254 287 /* 255 288 * This routine handles page faults. It determines the address, 256 289 * and the problem, and then passes it off to one of the appropriate 257 290 * routines. 258 291 * 259 - * error_code: 292 + * interruption code (int_code): 260 293 * 04 Protection -> Write-Protection (suprression) 261 294 * 10 Segment translation -> Not present (nullification) 262 295 * 11 Page translation -> Not present (nullification) 263 296 * 3b Region third trans. -> Not present (nullification) 264 297 */ 265 - static inline void 266 - do_exception(struct pt_regs *regs, unsigned long error_code, int write) 298 + static inline int do_exception(struct pt_regs *regs, int access, 299 + unsigned long trans_exc_code) 267 300 { 268 301 struct task_struct *tsk; 269 302 struct mm_struct *mm; 270 303 struct vm_area_struct *vma; 271 304 unsigned long address; 272 - int space; 273 - int si_code; 274 305 int fault; 275 306 276 - if (notify_page_fault(regs, error_code)) 277 - return; 307 + if (notify_page_fault(regs)) 308 + return 0; 278 309 279 310 tsk = current; 280 311 mm = tsk->mm; 281 - 282 - /* get the failing address and the affected space */ 283 - address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK; 284 - space = check_space(tsk); 285 312 286 313 /* 287 314 * Verify that the fault happened in user space, that 288 315 * we are not in an interrupt and that there is a 289 316 * user context. 290 317 */ 291 - if (unlikely(space == 0 || in_atomic() || !mm)) 292 - goto no_context; 318 + fault = VM_FAULT_BADCONTEXT; 319 + if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm)) 320 + goto out; 293 321 322 + address = trans_exc_code & __FAIL_ADDR_MASK; 294 323 /* 295 324 * When we get here, the fault happened in the current 296 325 * task's user address space, so we can switch on the ··· 320 309 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, 0, regs, address); 321 310 down_read(&mm->mmap_sem); 322 311 323 - si_code = SEGV_MAPERR; 312 + fault = VM_FAULT_BADMAP; 324 313 vma = find_vma(mm, address); 325 314 if (!vma) 326 - goto bad_area; 315 + goto out_up; 327 316 328 - #ifdef CONFIG_S390_EXEC_PROTECT 329 - if (unlikely((space == 2) && !(vma->vm_flags & VM_EXEC))) 330 - if (!signal_return(mm, regs, address, error_code)) 331 - /* 332 - * signal_return() has done an up_read(&mm->mmap_sem) 333 - * if it returns 0. 334 - */ 335 - return; 336 - #endif 337 - 338 - if (vma->vm_start <= address) 339 - goto good_area; 340 - if (!(vma->vm_flags & VM_GROWSDOWN)) 341 - goto bad_area; 342 - if (expand_stack(vma, address)) 343 - goto bad_area; 344 - /* 345 - * Ok, we have a good vm_area for this memory access, so 346 - * we can handle it.. 347 - */ 348 - good_area: 349 - si_code = SEGV_ACCERR; 350 - if (!write) { 351 - /* page not present, check vm flags */ 352 - if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) 353 - goto bad_area; 354 - } else { 355 - if (!(vma->vm_flags & VM_WRITE)) 356 - goto bad_area; 317 + if (unlikely(vma->vm_start > address)) { 318 + if (!(vma->vm_flags & VM_GROWSDOWN)) 319 + goto out_up; 320 + if (expand_stack(vma, address)) 321 + goto out_up; 357 322 } 323 + 324 + /* 325 + * Ok, we have a good vm_area for this memory access, so 326 + * we can handle it.. 327 + */ 328 + fault = VM_FAULT_BADACCESS; 329 + if (unlikely(!(vma->vm_flags & access))) 330 + goto out_up; 358 331 359 332 if (is_vm_hugetlb_page(vma)) 360 333 address &= HPAGE_MASK; ··· 347 352 * make sure we exit gracefully rather than endlessly redo 348 353 * the fault. 349 354 */ 350 - fault = handle_mm_fault(mm, vma, address, write ? FAULT_FLAG_WRITE : 0); 351 - if (unlikely(fault & VM_FAULT_ERROR)) { 352 - if (fault & VM_FAULT_OOM) { 353 - up_read(&mm->mmap_sem); 354 - pagefault_out_of_memory(); 355 - return; 356 - } else if (fault & VM_FAULT_SIGBUS) { 357 - do_sigbus(regs, error_code, address); 358 - return; 359 - } 360 - BUG(); 361 - } 355 + fault = handle_mm_fault(mm, vma, address, 356 + (access == VM_WRITE) ? FAULT_FLAG_WRITE : 0); 357 + if (unlikely(fault & VM_FAULT_ERROR)) 358 + goto out_up; 359 + 362 360 if (fault & VM_FAULT_MAJOR) { 363 361 tsk->maj_flt++; 364 362 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ, 1, 0, ··· 361 373 perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN, 1, 0, 362 374 regs, address); 363 375 } 364 - up_read(&mm->mmap_sem); 365 376 /* 366 377 * The instruction that caused the program check will 367 378 * be repeated. Don't signal single step via SIGTRAP. 368 379 */ 369 380 clear_tsk_thread_flag(tsk, TIF_SINGLE_STEP); 370 - return; 371 - 372 - /* 373 - * Something tried to access memory that isn't in our memory map.. 374 - * Fix it, but check if it's kernel or user first.. 375 - */ 376 - bad_area: 381 + fault = 0; 382 + out_up: 377 383 up_read(&mm->mmap_sem); 378 - 379 - /* User mode accesses just cause a SIGSEGV */ 380 - if (regs->psw.mask & PSW_MASK_PSTATE) { 381 - tsk->thread.prot_addr = address; 382 - tsk->thread.trap_no = error_code; 383 - do_sigsegv(regs, error_code, si_code, address); 384 - return; 385 - } 386 - 387 - no_context: 388 - do_no_context(regs, error_code, address); 384 + out: 385 + return fault; 389 386 } 390 387 391 - void __kprobes do_protection_exception(struct pt_regs *regs, 392 - long error_code) 388 + void __kprobes do_protection_exception(struct pt_regs *regs, long int_code) 393 389 { 390 + unsigned long trans_exc_code = S390_lowcore.trans_exc_code; 391 + int fault; 392 + 394 393 /* Protection exception is supressing, decrement psw address. */ 395 - regs->psw.addr -= (error_code >> 16); 394 + regs->psw.addr -= (int_code >> 16); 396 395 /* 397 396 * Check for low-address protection. This needs to be treated 398 397 * as a special case because the translation exception code 399 398 * field is not guaranteed to contain valid data in this case. 400 399 */ 401 - if (unlikely(!(S390_lowcore.trans_exc_code & 4))) { 402 - do_low_address(regs, error_code); 400 + if (unlikely(!(trans_exc_code & 4))) { 401 + do_low_address(regs, int_code, trans_exc_code); 403 402 return; 404 403 } 405 - do_exception(regs, 4, 1); 404 + fault = do_exception(regs, VM_WRITE, trans_exc_code); 405 + if (unlikely(fault)) 406 + do_fault_error(regs, 4, trans_exc_code, fault); 406 407 } 407 408 408 - void __kprobes do_dat_exception(struct pt_regs *regs, long error_code) 409 + void __kprobes do_dat_exception(struct pt_regs *regs, long int_code) 409 410 { 410 - do_exception(regs, error_code & 0xff, 0); 411 + unsigned long trans_exc_code = S390_lowcore.trans_exc_code; 412 + int access, fault; 413 + 414 + access = VM_READ | VM_EXEC | VM_WRITE; 415 + #ifdef CONFIG_S390_EXEC_PROTECT 416 + if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_SECONDARY && 417 + (trans_exc_code & 3) == 0) 418 + access = VM_EXEC; 419 + #endif 420 + fault = do_exception(regs, access, trans_exc_code); 421 + if (unlikely(fault)) 422 + do_fault_error(regs, int_code & 255, trans_exc_code, fault); 411 423 } 412 424 413 425 #ifdef CONFIG_64BIT 414 - void __kprobes do_asce_exception(struct pt_regs *regs, unsigned long error_code) 426 + void __kprobes do_asce_exception(struct pt_regs *regs, long int_code) 415 427 { 416 - struct mm_struct *mm; 428 + unsigned long trans_exc_code = S390_lowcore.trans_exc_code; 429 + struct mm_struct *mm = current->mm; 417 430 struct vm_area_struct *vma; 418 - unsigned long address; 419 - int space; 420 431 421 - mm = current->mm; 422 - address = S390_lowcore.trans_exc_code & __FAIL_ADDR_MASK; 423 - space = check_space(current); 424 - 425 - if (unlikely(space == 0 || in_atomic() || !mm)) 432 + if (unlikely(!user_space_fault(trans_exc_code) || in_atomic() || !mm)) 426 433 goto no_context; 427 434 428 435 local_irq_enable(); 429 436 430 437 down_read(&mm->mmap_sem); 431 - vma = find_vma(mm, address); 438 + vma = find_vma(mm, trans_exc_code & __FAIL_ADDR_MASK); 432 439 up_read(&mm->mmap_sem); 433 440 434 441 if (vma) { ··· 433 450 434 451 /* User mode accesses just cause a SIGSEGV */ 435 452 if (regs->psw.mask & PSW_MASK_PSTATE) { 436 - current->thread.prot_addr = address; 437 - current->thread.trap_no = error_code; 438 - do_sigsegv(regs, error_code, SEGV_MAPERR, address); 453 + do_sigsegv(regs, int_code, SEGV_MAPERR, trans_exc_code); 439 454 return; 440 455 } 441 456 442 457 no_context: 443 - do_no_context(regs, error_code, address); 458 + do_no_context(regs, int_code, trans_exc_code); 444 459 } 445 460 #endif 461 + 462 + int __handle_fault(unsigned long uaddr, unsigned long int_code, int write_user) 463 + { 464 + struct pt_regs regs; 465 + int access, fault; 466 + 467 + regs.psw.mask = psw_kernel_bits; 468 + if (!irqs_disabled()) 469 + regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT; 470 + regs.psw.addr = (unsigned long) __builtin_return_address(0); 471 + regs.psw.addr |= PSW_ADDR_AMODE; 472 + uaddr &= PAGE_MASK; 473 + access = write_user ? VM_WRITE : VM_READ; 474 + fault = do_exception(&regs, access, uaddr | 2); 475 + if (unlikely(fault)) { 476 + if (fault & VM_FAULT_OOM) { 477 + pagefault_out_of_memory(); 478 + fault = 0; 479 + } else if (fault & VM_FAULT_SIGBUS) 480 + do_sigbus(&regs, int_code, uaddr); 481 + } 482 + return fault ? -EFAULT : 0; 483 + } 446 484 447 485 #ifdef CONFIG_PFAULT 448 486 /* ··· 526 522 : : "a" (&refbk), "m" (refbk) : "cc"); 527 523 } 528 524 529 - static void pfault_interrupt(__u16 error_code) 525 + static void pfault_interrupt(__u16 int_code) 530 526 { 531 527 struct task_struct *tsk; 532 528 __u16 subcode;
+1 -1
arch/s390/mm/pgtable.c
··· 269 269 struct mm_struct *mm, *old_mm; 270 270 271 271 /* Do we have switched amode? If no, we cannot do sie */ 272 - if (!switch_amode) 272 + if (user_mode == HOME_SPACE_MODE) 273 273 return -EINVAL; 274 274 275 275 /* Do we have pgstes? if yes, we are done */
+8 -3
arch/s390/mm/vmem.c
··· 70 70 pte = alloc_bootmem(PTRS_PER_PTE * sizeof(pte_t)); 71 71 if (!pte) 72 72 return NULL; 73 - clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY, 74 - PTRS_PER_PTE * sizeof(pte_t)); 73 + if (MACHINE_HAS_HPAGE) 74 + clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY | _PAGE_CO, 75 + PTRS_PER_PTE * sizeof(pte_t)); 76 + else 77 + clear_table((unsigned long *) pte, _PAGE_TYPE_EMPTY, 78 + PTRS_PER_PTE * sizeof(pte_t)); 75 79 return pte; 76 80 } 77 81 ··· 116 112 if (MACHINE_HAS_HPAGE && !(address & ~HPAGE_MASK) && 117 113 (address + HPAGE_SIZE <= start + size) && 118 114 (address >= HPAGE_SIZE)) { 119 - pte_val(pte) |= _SEGMENT_ENTRY_LARGE; 115 + pte_val(pte) |= _SEGMENT_ENTRY_LARGE | 116 + _SEGMENT_ENTRY_CO; 120 117 pmd_val(*pm_dir) = pte_val(pte); 121 118 address += HPAGE_SIZE - PAGE_SIZE; 122 119 continue;
+169 -80
drivers/s390/block/dasd.c
··· 24 24 #include <asm/ccwdev.h> 25 25 #include <asm/ebcdic.h> 26 26 #include <asm/idals.h> 27 - #include <asm/todclk.h> 28 27 #include <asm/itcw.h> 29 28 30 29 /* This is ugly... */ ··· 63 64 static void dasd_return_cqr_cb(struct dasd_ccw_req *, void *); 64 65 static void dasd_device_timeout(unsigned long); 65 66 static void dasd_block_timeout(unsigned long); 67 + static void __dasd_process_erp(struct dasd_device *, struct dasd_ccw_req *); 66 68 67 69 /* 68 70 * SECTION: Operations on the device structure. ··· 960 960 device = (struct dasd_device *) ptr; 961 961 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 962 962 /* re-activate request queue */ 963 - device->stopped &= ~DASD_STOPPED_PENDING; 963 + dasd_device_remove_stop_bits(device, DASD_STOPPED_PENDING); 964 964 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 965 965 dasd_schedule_device_bh(device); 966 966 } ··· 994 994 return; 995 995 cqr = (struct dasd_ccw_req *) intparm; 996 996 if (cqr->status != DASD_CQR_IN_IO) { 997 - DBF_EVENT(DBF_DEBUG, 998 - "invalid status in handle_killed_request: " 999 - "bus_id %s, status %02x", 1000 - dev_name(&cdev->dev), cqr->status); 997 + DBF_EVENT_DEVID(DBF_DEBUG, cdev, 998 + "invalid status in handle_killed_request: " 999 + "%02x", cqr->status); 1001 1000 return; 1002 1001 } 1003 1002 ··· 1022 1023 /* First of all start sense subsystem status request. */ 1023 1024 dasd_eer_snss(device); 1024 1025 1025 - device->stopped &= ~DASD_STOPPED_PENDING; 1026 + dasd_device_remove_stop_bits(device, DASD_STOPPED_PENDING); 1026 1027 dasd_schedule_device_bh(device); 1027 1028 if (device->block) 1028 1029 dasd_schedule_block_bh(device->block); ··· 1044 1045 case -EIO: 1045 1046 break; 1046 1047 case -ETIMEDOUT: 1047 - DBF_EVENT(DBF_WARNING, "%s(%s): request timed out\n", 1048 - __func__, dev_name(&cdev->dev)); 1048 + DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: " 1049 + "request timed out\n", __func__); 1049 1050 break; 1050 1051 default: 1051 - DBF_EVENT(DBF_WARNING, "%s(%s): unknown error %ld\n", 1052 - __func__, dev_name(&cdev->dev), PTR_ERR(irb)); 1052 + DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s: " 1053 + "unknown error %ld\n", __func__, 1054 + PTR_ERR(irb)); 1053 1055 } 1054 1056 dasd_handle_killed_request(cdev, intparm); 1055 1057 return; ··· 1405 1405 tasklet_hi_schedule(&device->tasklet); 1406 1406 } 1407 1407 1408 + void dasd_device_set_stop_bits(struct dasd_device *device, int bits) 1409 + { 1410 + device->stopped |= bits; 1411 + } 1412 + EXPORT_SYMBOL_GPL(dasd_device_set_stop_bits); 1413 + 1414 + void dasd_device_remove_stop_bits(struct dasd_device *device, int bits) 1415 + { 1416 + device->stopped &= ~bits; 1417 + if (!device->stopped) 1418 + wake_up(&generic_waitq); 1419 + } 1420 + EXPORT_SYMBOL_GPL(dasd_device_remove_stop_bits); 1421 + 1408 1422 /* 1409 1423 * Queue a request to the head of the device ccw_queue. 1410 1424 * Start the I/O if possible. ··· 1479 1465 } 1480 1466 1481 1467 /* 1468 + * checks if error recovery is necessary, returns 1 if yes, 0 otherwise. 1469 + */ 1470 + static int __dasd_sleep_on_erp(struct dasd_ccw_req *cqr) 1471 + { 1472 + struct dasd_device *device; 1473 + dasd_erp_fn_t erp_fn; 1474 + 1475 + if (cqr->status == DASD_CQR_FILLED) 1476 + return 0; 1477 + device = cqr->startdev; 1478 + if (test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags)) { 1479 + if (cqr->status == DASD_CQR_TERMINATED) { 1480 + device->discipline->handle_terminated_request(cqr); 1481 + return 1; 1482 + } 1483 + if (cqr->status == DASD_CQR_NEED_ERP) { 1484 + erp_fn = device->discipline->erp_action(cqr); 1485 + erp_fn(cqr); 1486 + return 1; 1487 + } 1488 + if (cqr->status == DASD_CQR_FAILED) 1489 + dasd_log_sense(cqr, &cqr->irb); 1490 + if (cqr->refers) { 1491 + __dasd_process_erp(device, cqr); 1492 + return 1; 1493 + } 1494 + } 1495 + return 0; 1496 + } 1497 + 1498 + static int __dasd_sleep_on_loop_condition(struct dasd_ccw_req *cqr) 1499 + { 1500 + if (test_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags)) { 1501 + if (cqr->refers) /* erp is not done yet */ 1502 + return 1; 1503 + return ((cqr->status != DASD_CQR_DONE) && 1504 + (cqr->status != DASD_CQR_FAILED)); 1505 + } else 1506 + return (cqr->status == DASD_CQR_FILLED); 1507 + } 1508 + 1509 + static int _dasd_sleep_on(struct dasd_ccw_req *maincqr, int interruptible) 1510 + { 1511 + struct dasd_device *device; 1512 + int rc; 1513 + struct list_head ccw_queue; 1514 + struct dasd_ccw_req *cqr; 1515 + 1516 + INIT_LIST_HEAD(&ccw_queue); 1517 + maincqr->status = DASD_CQR_FILLED; 1518 + device = maincqr->startdev; 1519 + list_add(&maincqr->blocklist, &ccw_queue); 1520 + for (cqr = maincqr; __dasd_sleep_on_loop_condition(cqr); 1521 + cqr = list_first_entry(&ccw_queue, 1522 + struct dasd_ccw_req, blocklist)) { 1523 + 1524 + if (__dasd_sleep_on_erp(cqr)) 1525 + continue; 1526 + if (cqr->status != DASD_CQR_FILLED) /* could be failed */ 1527 + continue; 1528 + 1529 + /* Non-temporary stop condition will trigger fail fast */ 1530 + if (device->stopped & ~DASD_STOPPED_PENDING && 1531 + test_bit(DASD_CQR_FLAGS_FAILFAST, &cqr->flags) && 1532 + (!dasd_eer_enabled(device))) { 1533 + cqr->status = DASD_CQR_FAILED; 1534 + continue; 1535 + } 1536 + 1537 + /* Don't try to start requests if device is stopped */ 1538 + if (interruptible) { 1539 + rc = wait_event_interruptible( 1540 + generic_waitq, !(device->stopped)); 1541 + if (rc == -ERESTARTSYS) { 1542 + cqr->status = DASD_CQR_FAILED; 1543 + maincqr->intrc = rc; 1544 + continue; 1545 + } 1546 + } else 1547 + wait_event(generic_waitq, !(device->stopped)); 1548 + 1549 + cqr->callback = dasd_wakeup_cb; 1550 + cqr->callback_data = (void *) &generic_waitq; 1551 + dasd_add_request_tail(cqr); 1552 + if (interruptible) { 1553 + rc = wait_event_interruptible( 1554 + generic_waitq, _wait_for_wakeup(cqr)); 1555 + if (rc == -ERESTARTSYS) { 1556 + dasd_cancel_req(cqr); 1557 + /* wait (non-interruptible) for final status */ 1558 + wait_event(generic_waitq, 1559 + _wait_for_wakeup(cqr)); 1560 + cqr->status = DASD_CQR_FAILED; 1561 + maincqr->intrc = rc; 1562 + continue; 1563 + } 1564 + } else 1565 + wait_event(generic_waitq, _wait_for_wakeup(cqr)); 1566 + } 1567 + 1568 + maincqr->endclk = get_clock(); 1569 + if ((maincqr->status != DASD_CQR_DONE) && 1570 + (maincqr->intrc != -ERESTARTSYS)) 1571 + dasd_log_sense(maincqr, &maincqr->irb); 1572 + if (maincqr->status == DASD_CQR_DONE) 1573 + rc = 0; 1574 + else if (maincqr->intrc) 1575 + rc = maincqr->intrc; 1576 + else 1577 + rc = -EIO; 1578 + return rc; 1579 + } 1580 + 1581 + /* 1482 1582 * Queue a request to the tail of the device ccw_queue and wait for 1483 1583 * it's completion. 1484 1584 */ 1485 1585 int dasd_sleep_on(struct dasd_ccw_req *cqr) 1486 1586 { 1487 - struct dasd_device *device; 1488 - int rc; 1489 - 1490 - device = cqr->startdev; 1491 - 1492 - cqr->callback = dasd_wakeup_cb; 1493 - cqr->callback_data = (void *) &generic_waitq; 1494 - dasd_add_request_tail(cqr); 1495 - wait_event(generic_waitq, _wait_for_wakeup(cqr)); 1496 - 1497 - if (cqr->status == DASD_CQR_DONE) 1498 - rc = 0; 1499 - else if (cqr->intrc) 1500 - rc = cqr->intrc; 1501 - else 1502 - rc = -EIO; 1503 - return rc; 1587 + return _dasd_sleep_on(cqr, 0); 1504 1588 } 1505 1589 1506 1590 /* ··· 1607 1495 */ 1608 1496 int dasd_sleep_on_interruptible(struct dasd_ccw_req *cqr) 1609 1497 { 1610 - struct dasd_device *device; 1611 - int rc; 1612 - 1613 - device = cqr->startdev; 1614 - cqr->callback = dasd_wakeup_cb; 1615 - cqr->callback_data = (void *) &generic_waitq; 1616 - dasd_add_request_tail(cqr); 1617 - rc = wait_event_interruptible(generic_waitq, _wait_for_wakeup(cqr)); 1618 - if (rc == -ERESTARTSYS) { 1619 - dasd_cancel_req(cqr); 1620 - /* wait (non-interruptible) for final status */ 1621 - wait_event(generic_waitq, _wait_for_wakeup(cqr)); 1622 - cqr->intrc = rc; 1623 - } 1624 - 1625 - if (cqr->status == DASD_CQR_DONE) 1626 - rc = 0; 1627 - else if (cqr->intrc) 1628 - rc = cqr->intrc; 1629 - else 1630 - rc = -EIO; 1631 - return rc; 1498 + return _dasd_sleep_on(cqr, 1); 1632 1499 } 1633 1500 1634 1501 /* ··· 1721 1630 block = (struct dasd_block *) ptr; 1722 1631 spin_lock_irqsave(get_ccwdev_lock(block->base->cdev), flags); 1723 1632 /* re-activate request queue */ 1724 - block->base->stopped &= ~DASD_STOPPED_PENDING; 1633 + dasd_device_remove_stop_bits(block->base, DASD_STOPPED_PENDING); 1725 1634 spin_unlock_irqrestore(get_ccwdev_lock(block->base->cdev), flags); 1726 1635 dasd_schedule_block_bh(block); 1727 1636 } ··· 1748 1657 /* 1749 1658 * Process finished error recovery ccw. 1750 1659 */ 1751 - static inline void __dasd_block_process_erp(struct dasd_block *block, 1752 - struct dasd_ccw_req *cqr) 1660 + static void __dasd_process_erp(struct dasd_device *device, 1661 + struct dasd_ccw_req *cqr) 1753 1662 { 1754 1663 dasd_erp_fn_t erp_fn; 1755 - struct dasd_device *device = block->base; 1756 1664 1757 1665 if (cqr->status == DASD_CQR_DONE) 1758 1666 DBF_DEV_EVENT(DBF_NOTICE, device, "%s", "ERP successful"); ··· 1815 1725 */ 1816 1726 if (!list_empty(&block->ccw_queue)) 1817 1727 break; 1818 - spin_lock_irqsave(get_ccwdev_lock(basedev->cdev), flags); 1819 - basedev->stopped |= DASD_STOPPED_PENDING; 1820 - spin_unlock_irqrestore(get_ccwdev_lock(basedev->cdev), flags); 1728 + spin_lock_irqsave( 1729 + get_ccwdev_lock(basedev->cdev), flags); 1730 + dasd_device_set_stop_bits(basedev, 1731 + DASD_STOPPED_PENDING); 1732 + spin_unlock_irqrestore( 1733 + get_ccwdev_lock(basedev->cdev), flags); 1821 1734 dasd_block_set_timer(block, HZ/2); 1822 1735 break; 1823 1736 } ··· 1906 1813 cqr->status = DASD_CQR_FILLED; 1907 1814 cqr->retries = 255; 1908 1815 spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); 1909 - base->stopped |= DASD_STOPPED_QUIESCE; 1816 + dasd_device_set_stop_bits(base, DASD_STOPPED_QUIESCE); 1910 1817 spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), 1911 1818 flags); 1912 1819 goto restart; ··· 1914 1821 1915 1822 /* Process finished ERP request. */ 1916 1823 if (cqr->refers) { 1917 - __dasd_block_process_erp(block, cqr); 1824 + __dasd_process_erp(base, cqr); 1918 1825 goto restart; 1919 1826 } 1920 1827 ··· 2045 1952 /* Process finished ERP request. */ 2046 1953 if (cqr->refers) { 2047 1954 spin_lock_bh(&block->queue_lock); 2048 - __dasd_block_process_erp(block, cqr); 1955 + __dasd_process_erp(block->base, cqr); 2049 1956 spin_unlock_bh(&block->queue_lock); 2050 1957 /* restart list_for_xx loop since dasd_process_erp 2051 1958 * might remove multiple elements */ ··· 2301 2208 { 2302 2209 int ret; 2303 2210 2304 - ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); 2305 - if (ret) { 2306 - DBF_EVENT(DBF_WARNING, 2307 - "dasd_generic_probe: could not set ccw-device options " 2308 - "for %s\n", dev_name(&cdev->dev)); 2309 - return ret; 2310 - } 2311 2211 ret = dasd_add_sysfs_files(cdev); 2312 2212 if (ret) { 2313 - DBF_EVENT(DBF_WARNING, 2314 - "dasd_generic_probe: could not add sysfs entries " 2315 - "for %s\n", dev_name(&cdev->dev)); 2213 + DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s", 2214 + "dasd_generic_probe: could not add " 2215 + "sysfs entries"); 2316 2216 return ret; 2317 2217 } 2318 2218 cdev->handler = &dasd_int_handler; ··· 2504 2418 cqr->status = DASD_CQR_QUEUED; 2505 2419 cqr->retries++; 2506 2420 } 2507 - device->stopped |= DASD_STOPPED_DC_WAIT; 2421 + dasd_device_set_stop_bits(device, DASD_STOPPED_DC_WAIT); 2508 2422 dasd_device_clear_timer(device); 2509 2423 dasd_schedule_device_bh(device); 2510 2424 ret = 1; 2511 2425 break; 2512 2426 case CIO_OPER: 2513 2427 /* FIXME: add a sanity check. */ 2514 - device->stopped &= ~DASD_STOPPED_DC_WAIT; 2428 + dasd_device_remove_stop_bits(device, DASD_STOPPED_DC_WAIT); 2515 2429 if (device->stopped & DASD_UNRESUMED_PM) { 2516 - device->stopped &= ~DASD_UNRESUMED_PM; 2430 + dasd_device_remove_stop_bits(device, DASD_UNRESUMED_PM); 2517 2431 dasd_restore_device(device); 2518 2432 ret = 1; 2519 2433 break; ··· 2538 2452 if (IS_ERR(device)) 2539 2453 return PTR_ERR(device); 2540 2454 /* disallow new I/O */ 2541 - device->stopped |= DASD_STOPPED_PM; 2455 + dasd_device_set_stop_bits(device, DASD_STOPPED_PM); 2542 2456 /* clear active requests */ 2543 2457 INIT_LIST_HEAD(&freeze_queue); 2544 2458 spin_lock_irq(get_ccwdev_lock(cdev)); ··· 2590 2504 return PTR_ERR(device); 2591 2505 2592 2506 /* allow new IO again */ 2593 - device->stopped &= ~DASD_STOPPED_PM; 2594 - device->stopped &= ~DASD_UNRESUMED_PM; 2507 + dasd_device_remove_stop_bits(device, 2508 + (DASD_STOPPED_PM | DASD_UNRESUMED_PM)); 2595 2509 2596 2510 dasd_schedule_device_bh(device); 2597 2511 2598 - if (device->discipline->restore) 2512 + /* 2513 + * call discipline restore function 2514 + * if device is stopped do nothing e.g. for disconnected devices 2515 + */ 2516 + if (device->discipline->restore && !(device->stopped)) 2599 2517 rc = device->discipline->restore(device); 2600 - if (rc) 2518 + if (rc || device->stopped) 2601 2519 /* 2602 2520 * if the resume failed for the DASD we put it in 2603 2521 * an UNRESUMED stop state ··· 2651 2561 cqr->startdev = device; 2652 2562 cqr->memdev = device; 2653 2563 cqr->expires = 10*HZ; 2654 - clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 2655 - cqr->retries = 2; 2564 + cqr->retries = 256; 2656 2565 cqr->buildclk = get_clock(); 2657 2566 cqr->status = DASD_CQR_FILLED; 2658 2567 return cqr;
+34 -15
drivers/s390/block/dasd_3990_erp.c
··· 12 12 #include <linux/timer.h> 13 13 #include <linux/slab.h> 14 14 #include <asm/idals.h> 15 - #include <asm/todclk.h> 16 15 17 16 #define PRINTK_HEADER "dasd_erp(3990): " 18 17 ··· 69 70 * processing until the started timer has expired or an related 70 71 * interrupt was received. 71 72 */ 72 - static void 73 - dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires) 73 + static void dasd_3990_erp_block_queue(struct dasd_ccw_req *erp, int expires) 74 74 { 75 75 76 76 struct dasd_device *device = erp->startdev; ··· 79 81 "blocking request queue for %is", expires/HZ); 80 82 81 83 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 82 - device->stopped |= DASD_STOPPED_PENDING; 84 + dasd_device_set_stop_bits(device, DASD_STOPPED_PENDING); 83 85 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 84 86 erp->status = DASD_CQR_FILLED; 85 - dasd_block_set_timer(device->block, expires); 87 + if (erp->block) 88 + dasd_block_set_timer(erp->block, expires); 89 + else 90 + dasd_device_set_timer(device, expires); 86 91 } 87 92 88 93 /* ··· 244 243 * DESCRIPTION 245 244 * Setup ERP to do the ERP action 1 (see Reference manual). 246 245 * Repeat the operation on a different channel path. 247 - * If all alternate paths have been tried, the request is posted with a 248 - * permanent error. 249 - * Note: duplex handling is not implemented (yet). 246 + * As deviation from the recommended recovery action, we reset the path mask 247 + * after we have tried each path and go through all paths a second time. 248 + * This will cover situations where only one path at a time is actually down, 249 + * but all paths fail and recover just with the same sequence and timing as 250 + * we try to use them (flapping links). 251 + * If all alternate paths have been tried twice, the request is posted with 252 + * a permanent error. 250 253 * 251 254 * PARAMETER 252 255 * erp pointer to the current ERP ··· 259 254 * erp pointer to the ERP 260 255 * 261 256 */ 262 - static struct dasd_ccw_req * 263 - dasd_3990_erp_action_1(struct dasd_ccw_req * erp) 257 + static struct dasd_ccw_req *dasd_3990_erp_action_1_sec(struct dasd_ccw_req *erp) 264 258 { 265 - 266 - erp->function = dasd_3990_erp_action_1; 267 - 259 + erp->function = dasd_3990_erp_action_1_sec; 268 260 dasd_3990_erp_alternate_path(erp); 269 - 270 261 return erp; 262 + } 271 263 272 - } /* end dasd_3990_erp_action_1 */ 264 + static struct dasd_ccw_req *dasd_3990_erp_action_1(struct dasd_ccw_req *erp) 265 + { 266 + erp->function = dasd_3990_erp_action_1; 267 + dasd_3990_erp_alternate_path(erp); 268 + if (erp->status == DASD_CQR_FAILED) { 269 + erp->status = DASD_CQR_FILLED; 270 + erp->retries = 10; 271 + erp->lpm = LPM_ANYPATH; 272 + erp->function = dasd_3990_erp_action_1_sec; 273 + } 274 + return erp; 275 + } /* end dasd_3990_erp_action_1(b) */ 273 276 274 277 /* 275 278 * DASD_3990_ERP_ACTION_4 ··· 2308 2295 return cqr; 2309 2296 } 2310 2297 2298 + ccw = cqr->cpaddr; 2311 2299 if (cqr->cpmode == 1) { 2312 2300 /* make a shallow copy of the original tcw but set new tsb */ 2313 2301 erp->cpmode = 1; ··· 2317 2303 tsb = (struct tsb *) &tcw[1]; 2318 2304 *tcw = *((struct tcw *)cqr->cpaddr); 2319 2305 tcw->tsb = (long)tsb; 2306 + } else if (ccw->cmd_code == DASD_ECKD_CCW_PSF) { 2307 + /* PSF cannot be chained from NOOP/TIC */ 2308 + erp->cpaddr = cqr->cpaddr; 2320 2309 } else { 2321 2310 /* initialize request with default TIC to current ERP/CQR */ 2322 2311 ccw = erp->cpaddr; ··· 2504 2487 2505 2488 erp = dasd_3990_erp_action_1(erp); 2506 2489 2490 + } else if (erp->function == dasd_3990_erp_action_1_sec) { 2491 + erp = dasd_3990_erp_action_1_sec(erp); 2507 2492 } else if (erp->function == dasd_3990_erp_action_5) { 2508 2493 2509 2494 /* retries have not been successful */
+70 -7
drivers/s390/block/dasd_alias.c
··· 152 152 INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work); 153 153 INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work); 154 154 spin_lock_init(&lcu->lock); 155 + init_completion(&lcu->lcu_setup); 155 156 return lcu; 156 157 157 158 out_err4: ··· 238 237 spin_unlock_irqrestore(&aliastree.lock, flags); 239 238 240 239 return is_lcu_known; 240 + } 241 + 242 + /* 243 + * The first device to be registered on an LCU will have to do 244 + * some additional setup steps to configure that LCU on the 245 + * storage server. All further devices should wait with their 246 + * initialization until the first device is done. 247 + * To synchronize this work, the first device will call 248 + * dasd_alias_lcu_setup_complete when it is done, and all 249 + * other devices will wait for it with dasd_alias_wait_for_lcu_setup. 250 + */ 251 + void dasd_alias_lcu_setup_complete(struct dasd_device *device) 252 + { 253 + struct dasd_eckd_private *private; 254 + unsigned long flags; 255 + struct alias_server *server; 256 + struct alias_lcu *lcu; 257 + struct dasd_uid *uid; 258 + 259 + private = (struct dasd_eckd_private *) device->private; 260 + uid = &private->uid; 261 + lcu = NULL; 262 + spin_lock_irqsave(&aliastree.lock, flags); 263 + server = _find_server(uid); 264 + if (server) 265 + lcu = _find_lcu(server, uid); 266 + spin_unlock_irqrestore(&aliastree.lock, flags); 267 + if (!lcu) { 268 + DBF_EVENT_DEVID(DBF_ERR, device->cdev, 269 + "could not find lcu for %04x %02x", 270 + uid->ssid, uid->real_unit_addr); 271 + WARN_ON(1); 272 + return; 273 + } 274 + complete_all(&lcu->lcu_setup); 275 + } 276 + 277 + void dasd_alias_wait_for_lcu_setup(struct dasd_device *device) 278 + { 279 + struct dasd_eckd_private *private; 280 + unsigned long flags; 281 + struct alias_server *server; 282 + struct alias_lcu *lcu; 283 + struct dasd_uid *uid; 284 + 285 + private = (struct dasd_eckd_private *) device->private; 286 + uid = &private->uid; 287 + lcu = NULL; 288 + spin_lock_irqsave(&aliastree.lock, flags); 289 + server = _find_server(uid); 290 + if (server) 291 + lcu = _find_lcu(server, uid); 292 + spin_unlock_irqrestore(&aliastree.lock, flags); 293 + if (!lcu) { 294 + DBF_EVENT_DEVID(DBF_ERR, device->cdev, 295 + "could not find lcu for %04x %02x", 296 + uid->ssid, uid->real_unit_addr); 297 + WARN_ON(1); 298 + return; 299 + } 300 + wait_for_completion(&lcu->lcu_setup); 241 301 } 242 302 243 303 /* ··· 817 755 { 818 756 /* If pos == device then device is already locked! */ 819 757 if (pos == device) { 820 - pos->stopped |= DASD_STOPPED_SU; 758 + dasd_device_set_stop_bits(pos, DASD_STOPPED_SU); 821 759 return; 822 760 } 823 761 spin_lock(get_ccwdev_lock(pos->cdev)); 824 - pos->stopped |= DASD_STOPPED_SU; 762 + dasd_device_set_stop_bits(pos, DASD_STOPPED_SU); 825 763 spin_unlock(get_ccwdev_lock(pos->cdev)); 826 764 } 827 765 ··· 855 793 856 794 list_for_each_entry(device, &lcu->active_devices, alias_list) { 857 795 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 858 - device->stopped &= ~DASD_STOPPED_SU; 796 + dasd_device_remove_stop_bits(device, DASD_STOPPED_SU); 859 797 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 860 798 } 861 799 862 800 list_for_each_entry(device, &lcu->inactive_devices, alias_list) { 863 801 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 864 - device->stopped &= ~DASD_STOPPED_SU; 802 + dasd_device_remove_stop_bits(device, DASD_STOPPED_SU); 865 803 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 866 804 } 867 805 868 806 list_for_each_entry(pavgroup, &lcu->grouplist, group) { 869 807 list_for_each_entry(device, &pavgroup->baselist, alias_list) { 870 808 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 871 - device->stopped &= ~DASD_STOPPED_SU; 809 + dasd_device_remove_stop_bits(device, DASD_STOPPED_SU); 872 810 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), 873 811 flags); 874 812 } 875 813 list_for_each_entry(device, &pavgroup->aliaslist, alias_list) { 876 814 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 877 - device->stopped &= ~DASD_STOPPED_SU; 815 + dasd_device_remove_stop_bits(device, DASD_STOPPED_SU); 878 816 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), 879 817 flags); 880 818 } ··· 898 836 899 837 /* 2. reset summary unit check */ 900 838 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); 901 - device->stopped &= ~(DASD_STOPPED_SU | DASD_STOPPED_PENDING); 839 + dasd_device_remove_stop_bits(device, 840 + (DASD_STOPPED_SU | DASD_STOPPED_PENDING)); 902 841 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); 903 842 reset_summary_unit_check(lcu, device, suc_data->reason); 904 843
+16 -4
drivers/s390/block/dasd_diag.c
··· 24 24 #include <asm/ebcdic.h> 25 25 #include <asm/io.h> 26 26 #include <asm/s390_ext.h> 27 - #include <asm/todclk.h> 28 27 #include <asm/vtoc.h> 29 28 #include <asm/diag.h> 30 29 ··· 144 145 145 146 mdsk_term_io(device); 146 147 rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); 148 + if (rc == 4) { 149 + if (!(device->features & DASD_FEATURE_READONLY)) { 150 + dev_warn(&device->cdev->dev, 151 + "The access mode of a DIAG device changed" 152 + " to read-only"); 153 + device->features |= DASD_FEATURE_READONLY; 154 + } 155 + rc = 0; 156 + } 147 157 if (rc) 148 158 dev_warn(&device->cdev->dev, "DIAG ERP failed with " 149 159 "rc=%d\n", rc); ··· 441 433 for (sb = 512; sb < bsize; sb = sb << 1) 442 434 block->s2b_shift++; 443 435 rc = mdsk_init_io(device, block->bp_block, 0, NULL); 444 - if (rc) { 436 + if (rc && (rc != 4)) { 445 437 dev_warn(&device->cdev->dev, "DIAG initialization " 446 438 "failed with rc=%d\n", rc); 447 439 rc = -EIO; 448 440 } else { 441 + if (rc == 4) 442 + device->features |= DASD_FEATURE_READONLY; 449 443 dev_info(&device->cdev->dev, 450 - "New DASD with %ld byte/block, total size %ld KB\n", 444 + "New DASD with %ld byte/block, total size %ld KB%s\n", 451 445 (unsigned long) block->bp_block, 452 446 (unsigned long) (block->blocks << 453 - block->s2b_shift) >> 1); 447 + block->s2b_shift) >> 1, 448 + (rc == 4) ? ", read-only device" : ""); 449 + rc = 0; 454 450 } 455 451 out_label: 456 452 free_page((long) label);
+111 -59
drivers/s390/block/dasd_eckd.c
··· 24 24 #include <asm/idals.h> 25 25 #include <asm/ebcdic.h> 26 26 #include <asm/io.h> 27 - #include <asm/todclk.h> 28 27 #include <asm/uaccess.h> 29 28 #include <asm/cio.h> 30 29 #include <asm/ccwdev.h> ··· 77 78 78 79 static struct ccw_driver dasd_eckd_driver; /* see below */ 79 80 81 + #define INIT_CQR_OK 0 82 + #define INIT_CQR_UNFORMATTED 1 83 + #define INIT_CQR_ERROR 2 84 + 85 + 80 86 /* initial attempt at a probe function. this can be simplified once 81 87 * the other detection code is gone */ 82 88 static int ··· 90 86 int ret; 91 87 92 88 /* set ECKD specific ccw-device options */ 93 - ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE); 89 + ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE | 90 + CCWDEV_DO_PATHGROUP | CCWDEV_DO_MULTIPATH); 94 91 if (ret) { 95 - DBF_EVENT(DBF_WARNING, 96 - "dasd_eckd_probe: could not set ccw-device options " 97 - "for %s\n", dev_name(&cdev->dev)); 92 + DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s", 93 + "dasd_eckd_probe: could not set " 94 + "ccw-device options"); 98 95 return ret; 99 96 } 100 97 ret = dasd_generic_probe(cdev, &dasd_eckd_discipline); ··· 754 749 cqr->block = NULL; 755 750 cqr->expires = 10*HZ; 756 751 cqr->lpm = lpm; 757 - clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 758 - cqr->retries = 2; 752 + cqr->retries = 256; 759 753 cqr->buildclk = get_clock(); 760 754 cqr->status = DASD_CQR_FILLED; 761 755 return cqr; ··· 889 885 rc = dasd_eckd_read_conf_lpm(device, &conf_data, 890 886 &conf_len, lpm); 891 887 if (rc && rc != -EOPNOTSUPP) { /* -EOPNOTSUPP is ok */ 892 - DBF_EVENT(DBF_WARNING, 888 + DBF_EVENT_DEVID(DBF_WARNING, device->cdev, 893 889 "Read configuration data returned " 894 - "error %d for device: %s", rc, 895 - dev_name(&device->cdev->dev)); 890 + "error %d", rc); 896 891 return rc; 897 892 } 898 893 if (conf_data == NULL) { 899 - DBF_EVENT(DBF_WARNING, "No configuration " 900 - "data retrieved for device: %s", 901 - dev_name(&device->cdev->dev)); 894 + DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", 895 + "No configuration data " 896 + "retrieved"); 902 897 continue; /* no error */ 903 898 } 904 899 /* save first valid configuration data */ ··· 944 941 sizeof(struct dasd_rssd_features)), 945 942 device); 946 943 if (IS_ERR(cqr)) { 947 - DBF_EVENT(DBF_WARNING, "Could not allocate initialization " 948 - "request for device: %s", 949 - dev_name(&device->cdev->dev)); 944 + DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", "Could not " 945 + "allocate initialization request"); 950 946 return PTR_ERR(cqr); 951 947 } 952 948 cqr->startdev = device; 953 949 cqr->memdev = device; 954 950 cqr->block = NULL; 955 - clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 956 - cqr->retries = 5; 951 + cqr->retries = 256; 957 952 cqr->expires = 10 * HZ; 958 953 959 954 /* Prepare for Read Subsystem Data */ ··· 1013 1012 } 1014 1013 psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data; 1015 1014 psf_ssc_data->order = PSF_ORDER_SSC; 1016 - psf_ssc_data->suborder = 0x40; 1015 + psf_ssc_data->suborder = 0xc0; 1017 1016 if (enable_pav) { 1018 - psf_ssc_data->suborder |= 0x88; 1017 + psf_ssc_data->suborder |= 0x08; 1019 1018 psf_ssc_data->reserved[0] = 0x88; 1020 1019 } 1021 1020 ccw = cqr->cpaddr; ··· 1026 1025 cqr->startdev = device; 1027 1026 cqr->memdev = device; 1028 1027 cqr->block = NULL; 1028 + cqr->retries = 256; 1029 1029 cqr->expires = 10*HZ; 1030 1030 cqr->buildclk = get_clock(); 1031 1031 cqr->status = DASD_CQR_FILLED; ··· 1059 1057 /* 1060 1058 * Valide storage server of current device. 1061 1059 */ 1062 - static int dasd_eckd_validate_server(struct dasd_device *device) 1060 + static void dasd_eckd_validate_server(struct dasd_device *device) 1063 1061 { 1064 1062 int rc; 1065 1063 struct dasd_eckd_private *private; ··· 1070 1068 else 1071 1069 enable_pav = 1; 1072 1070 rc = dasd_eckd_psf_ssc(device, enable_pav); 1071 + 1073 1072 /* may be requested feature is not available on server, 1074 1073 * therefore just report error and go ahead */ 1075 1074 private = (struct dasd_eckd_private *) device->private; 1076 - DBF_EVENT(DBF_WARNING, "PSF-SSC on storage subsystem %s.%s.%04x " 1077 - "returned rc=%d for device: %s", 1078 - private->uid.vendor, private->uid.serial, 1079 - private->uid.ssid, rc, dev_name(&device->cdev->dev)); 1080 - /* RE-Read Configuration Data */ 1081 - return dasd_eckd_read_conf(device); 1075 + DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "PSF-SSC for SSID %04x " 1076 + "returned rc=%d", private->uid.ssid, rc); 1082 1077 } 1083 1078 1084 1079 /* ··· 1089 1090 struct dasd_block *block; 1090 1091 int is_known, rc; 1091 1092 1093 + if (!ccw_device_is_pathgroup(device->cdev)) { 1094 + dev_warn(&device->cdev->dev, 1095 + "A channel path group could not be established\n"); 1096 + return -EIO; 1097 + } 1098 + if (!ccw_device_is_multipath(device->cdev)) { 1099 + dev_info(&device->cdev->dev, 1100 + "The DASD is not operating in multipath mode\n"); 1101 + } 1092 1102 private = (struct dasd_eckd_private *) device->private; 1093 1103 if (!private) { 1094 1104 private = kzalloc(sizeof(*private), GFP_KERNEL | GFP_DMA); ··· 1131 1123 if (private->uid.type == UA_BASE_DEVICE) { 1132 1124 block = dasd_alloc_block(); 1133 1125 if (IS_ERR(block)) { 1134 - DBF_EVENT(DBF_WARNING, "could not allocate dasd " 1135 - "block structure for device: %s", 1136 - dev_name(&device->cdev->dev)); 1126 + DBF_EVENT_DEVID(DBF_WARNING, device->cdev, "%s", 1127 + "could not allocate dasd " 1128 + "block structure"); 1137 1129 rc = PTR_ERR(block); 1138 1130 goto out_err1; 1139 1131 } ··· 1147 1139 rc = is_known; 1148 1140 goto out_err2; 1149 1141 } 1142 + /* 1143 + * dasd_eckd_vaildate_server is done on the first device that 1144 + * is found for an LCU. All later other devices have to wait 1145 + * for it, so they will read the correct feature codes. 1146 + */ 1150 1147 if (!is_known) { 1151 - /* new lcu found */ 1152 - rc = dasd_eckd_validate_server(device); /* will switch pav on */ 1153 - if (rc) 1154 - goto out_err3; 1155 - } 1148 + dasd_eckd_validate_server(device); 1149 + dasd_alias_lcu_setup_complete(device); 1150 + } else 1151 + dasd_alias_wait_for_lcu_setup(device); 1152 + 1153 + /* device may report different configuration data after LCU setup */ 1154 + rc = dasd_eckd_read_conf(device); 1155 + if (rc) 1156 + goto out_err3; 1156 1157 1157 1158 /* Read Feature Codes */ 1158 1159 dasd_eckd_read_features(device); ··· 1170 1153 rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, 1171 1154 &private->rdc_data, 64); 1172 1155 if (rc) { 1173 - DBF_EVENT(DBF_WARNING, 1174 - "Read device characteristics failed, rc=%d for " 1175 - "device: %s", rc, dev_name(&device->cdev->dev)); 1156 + DBF_EVENT_DEVID(DBF_WARNING, device->cdev, 1157 + "Read device characteristic failed, rc=%d", rc); 1176 1158 goto out_err3; 1177 1159 } 1178 1160 /* find the vaild cylinder size */ ··· 1272 1256 cqr->block = NULL; 1273 1257 cqr->startdev = device; 1274 1258 cqr->memdev = device; 1275 - cqr->retries = 0; 1259 + cqr->retries = 255; 1276 1260 cqr->buildclk = get_clock(); 1277 1261 cqr->status = DASD_CQR_FILLED; 1278 1262 return cqr; 1263 + } 1264 + 1265 + /* differentiate between 'no record found' and any other error */ 1266 + static int dasd_eckd_analysis_evaluation(struct dasd_ccw_req *init_cqr) 1267 + { 1268 + char *sense; 1269 + if (init_cqr->status == DASD_CQR_DONE) 1270 + return INIT_CQR_OK; 1271 + else if (init_cqr->status == DASD_CQR_NEED_ERP || 1272 + init_cqr->status == DASD_CQR_FAILED) { 1273 + sense = dasd_get_sense(&init_cqr->irb); 1274 + if (sense && (sense[1] & SNS1_NO_REC_FOUND)) 1275 + return INIT_CQR_UNFORMATTED; 1276 + else 1277 + return INIT_CQR_ERROR; 1278 + } else 1279 + return INIT_CQR_ERROR; 1279 1280 } 1280 1281 1281 1282 /* ··· 1302 1269 * dasd_eckd_do_analysis again (if the devices has not been marked 1303 1270 * for deletion in the meantime). 1304 1271 */ 1305 - static void 1306 - dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, void *data) 1272 + static void dasd_eckd_analysis_callback(struct dasd_ccw_req *init_cqr, 1273 + void *data) 1307 1274 { 1308 1275 struct dasd_eckd_private *private; 1309 1276 struct dasd_device *device; 1310 1277 1311 1278 device = init_cqr->startdev; 1312 1279 private = (struct dasd_eckd_private *) device->private; 1313 - private->init_cqr_status = init_cqr->status; 1280 + private->init_cqr_status = dasd_eckd_analysis_evaluation(init_cqr); 1314 1281 dasd_sfree_request(init_cqr, device); 1315 1282 dasd_kick_device(device); 1316 1283 } 1317 1284 1318 - static int 1319 - dasd_eckd_start_analysis(struct dasd_block *block) 1285 + static int dasd_eckd_start_analysis(struct dasd_block *block) 1320 1286 { 1321 1287 struct dasd_eckd_private *private; 1322 1288 struct dasd_ccw_req *init_cqr; ··· 1327 1295 init_cqr->callback = dasd_eckd_analysis_callback; 1328 1296 init_cqr->callback_data = NULL; 1329 1297 init_cqr->expires = 5*HZ; 1298 + /* first try without ERP, so we can later handle unformatted 1299 + * devices as special case 1300 + */ 1301 + clear_bit(DASD_CQR_FLAGS_USE_ERP, &init_cqr->flags); 1302 + init_cqr->retries = 0; 1330 1303 dasd_add_request_head(init_cqr); 1331 1304 return -EAGAIN; 1332 1305 } 1333 1306 1334 - static int 1335 - dasd_eckd_end_analysis(struct dasd_block *block) 1307 + static int dasd_eckd_end_analysis(struct dasd_block *block) 1336 1308 { 1337 1309 struct dasd_device *device; 1338 1310 struct dasd_eckd_private *private; 1339 1311 struct eckd_count *count_area; 1340 1312 unsigned int sb, blk_per_trk; 1341 1313 int status, i; 1314 + struct dasd_ccw_req *init_cqr; 1342 1315 1343 1316 device = block->base; 1344 1317 private = (struct dasd_eckd_private *) device->private; 1345 1318 status = private->init_cqr_status; 1346 1319 private->init_cqr_status = -1; 1347 - if (status != DASD_CQR_DONE) { 1348 - dev_warn(&device->cdev->dev, 1349 - "The DASD is not formatted\n"); 1320 + if (status == INIT_CQR_ERROR) { 1321 + /* try again, this time with full ERP */ 1322 + init_cqr = dasd_eckd_analysis_ccw(device); 1323 + dasd_sleep_on(init_cqr); 1324 + status = dasd_eckd_analysis_evaluation(init_cqr); 1325 + dasd_sfree_request(init_cqr, device); 1326 + } 1327 + 1328 + if (status == INIT_CQR_UNFORMATTED) { 1329 + dev_warn(&device->cdev->dev, "The DASD is not formatted\n"); 1350 1330 return -EMEDIUMTYPE; 1331 + } else if (status == INIT_CQR_ERROR) { 1332 + dev_err(&device->cdev->dev, 1333 + "Detecting the DASD disk layout failed because " 1334 + "of an I/O error\n"); 1335 + return -EIO; 1351 1336 } 1352 1337 1353 1338 private->uses_cdl = 1; ··· 1656 1607 } 1657 1608 fcp->startdev = device; 1658 1609 fcp->memdev = device; 1659 - clear_bit(DASD_CQR_FLAGS_USE_ERP, &fcp->flags); 1660 - fcp->retries = 5; /* set retry counter to enable default ERP */ 1610 + fcp->retries = 256; 1661 1611 fcp->buildclk = get_clock(); 1662 1612 fcp->status = DASD_CQR_FILLED; 1663 1613 return fcp; ··· 2738 2690 cqr->startdev = device; 2739 2691 cqr->memdev = device; 2740 2692 cqr->retries = 0; 2693 + clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags); 2741 2694 cqr->expires = 10 * HZ; 2742 2695 2743 2696 /* Prepare for Read Subsystem Data */ ··· 3289 3240 if (is_known < 0) 3290 3241 return is_known; 3291 3242 if (!is_known) { 3292 - /* new lcu found */ 3293 - rc = dasd_eckd_validate_server(device); /* will switch pav on */ 3294 - if (rc) 3295 - goto out_err; 3296 - } 3243 + dasd_eckd_validate_server(device); 3244 + dasd_alias_lcu_setup_complete(device); 3245 + } else 3246 + dasd_alias_wait_for_lcu_setup(device); 3247 + 3248 + /* RE-Read Configuration Data */ 3249 + rc = dasd_eckd_read_conf(device); 3250 + if (rc) 3251 + goto out_err; 3297 3252 3298 3253 /* Read Feature Codes */ 3299 3254 dasd_eckd_read_features(device); ··· 3306 3253 rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, 3307 3254 &temp_rdc_data, 64); 3308 3255 if (rc) { 3309 - DBF_EVENT(DBF_WARNING, 3310 - "Read device characteristics failed, rc=%d for " 3311 - "device: %s", rc, dev_name(&device->cdev->dev)); 3256 + DBF_EVENT_DEVID(DBF_WARNING, device->cdev, 3257 + "Read device characteristic failed, rc=%d", rc); 3312 3258 goto out_err; 3313 3259 } 3314 3260 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
+3 -1
drivers/s390/block/dasd_eckd.h
··· 414 414 struct summary_unit_check_work_data suc_data; 415 415 struct read_uac_work_data ruac_data; 416 416 struct dasd_ccw_req *rsu_cqr; 417 + struct completion lcu_setup; 417 418 }; 418 419 419 420 struct alias_pav_group { ··· 461 460 struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *); 462 461 void dasd_alias_handle_summary_unit_check(struct dasd_device *, struct irb *); 463 462 void dasd_eckd_reset_ccw_to_base_io(struct dasd_ccw_req *); 464 - 463 + void dasd_alias_lcu_setup_complete(struct dasd_device *); 464 + void dasd_alias_wait_for_lcu_setup(struct dasd_device *); 465 465 #endif /* DASD_ECKD_H */
-5
drivers/s390/block/dasd_eer.c
··· 536 536 eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL); 537 537 if (!eerb) 538 538 return -ENOMEM; 539 - lock_kernel(); 540 539 eerb->buffer_page_count = eer_pages; 541 540 if (eerb->buffer_page_count < 1 || 542 541 eerb->buffer_page_count > INT_MAX / PAGE_SIZE) { ··· 543 544 DBF_EVENT(DBF_WARNING, "can't open device since module " 544 545 "parameter eer_pages is smaller than 1 or" 545 546 " bigger than %d", (int)(INT_MAX / PAGE_SIZE)); 546 - unlock_kernel(); 547 547 return -EINVAL; 548 548 } 549 549 eerb->buffersize = eerb->buffer_page_count * PAGE_SIZE; ··· 550 552 GFP_KERNEL); 551 553 if (!eerb->buffer) { 552 554 kfree(eerb); 553 - unlock_kernel(); 554 555 return -ENOMEM; 555 556 } 556 557 if (dasd_eer_allocate_buffer_pages(eerb->buffer, 557 558 eerb->buffer_page_count)) { 558 559 kfree(eerb->buffer); 559 560 kfree(eerb); 560 - unlock_kernel(); 561 561 return -ENOMEM; 562 562 } 563 563 filp->private_data = eerb; ··· 563 567 list_add(&eerb->list, &bufferlist); 564 568 spin_unlock_irqrestore(&bufferlock, flags); 565 569 566 - unlock_kernel(); 567 570 return nonseekable_open(inp,filp); 568 571 } 569 572
+4 -7
drivers/s390/block/dasd_fba.c
··· 20 20 #include <asm/idals.h> 21 21 #include <asm/ebcdic.h> 22 22 #include <asm/io.h> 23 - #include <asm/todclk.h> 24 23 #include <asm/ccwdev.h> 25 24 26 25 #include "dasd_int.h" ··· 140 141 } 141 142 block = dasd_alloc_block(); 142 143 if (IS_ERR(block)) { 143 - DBF_EVENT(DBF_WARNING, "could not allocate dasd block " 144 - "structure for device: %s", 145 - dev_name(&device->cdev->dev)); 144 + DBF_EVENT_DEVID(DBF_WARNING, cdev, "%s", "could not allocate " 145 + "dasd block structure"); 146 146 device->private = NULL; 147 147 kfree(private); 148 148 return PTR_ERR(block); ··· 153 155 rc = dasd_generic_read_dev_chars(device, DASD_FBA_MAGIC, 154 156 &private->rdc_data, 32); 155 157 if (rc) { 156 - DBF_EVENT(DBF_WARNING, "Read device characteristics returned " 157 - "error %d for device: %s", 158 - rc, dev_name(&device->cdev->dev)); 158 + DBF_EVENT_DEVID(DBF_WARNING, cdev, "Read device " 159 + "characteristics returned error %d", rc); 159 160 device->block = NULL; 160 161 dasd_free_block(block); 161 162 device->private = NULL;
+13
drivers/s390/block/dasd_int.h
··· 108 108 d_data); \ 109 109 } while(0) 110 110 111 + #define DBF_EVENT_DEVID(d_level, d_cdev, d_str, d_data...) \ 112 + do { \ 113 + struct ccw_dev_id __dev_id; \ 114 + ccw_device_get_id(d_cdev, &__dev_id); \ 115 + debug_sprintf_event(dasd_debug_area, \ 116 + d_level, \ 117 + "0.%x.%04x " d_str "\n", \ 118 + __dev_id.ssid, __dev_id.devno, d_data); \ 119 + } while (0) 120 + 111 121 #define DBF_EXC(d_level, d_str, d_data...)\ 112 122 do { \ 113 123 debug_sprintf_exception(dasd_debug_area, \ ··· 604 594 605 595 int dasd_generic_read_dev_chars(struct dasd_device *, int, void *, int); 606 596 char *dasd_get_sense(struct irb *); 597 + 598 + void dasd_device_set_stop_bits(struct dasd_device *, int); 599 + void dasd_device_remove_stop_bits(struct dasd_device *, int); 607 600 608 601 /* externals in dasd_devmap.c */ 609 602 extern int dasd_max_devindex;
+2 -2
drivers/s390/block/dasd_ioctl.c
··· 101 101 pr_info("%s: The DASD has been put in the quiesce " 102 102 "state\n", dev_name(&base->cdev->dev)); 103 103 spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); 104 - base->stopped |= DASD_STOPPED_QUIESCE; 104 + dasd_device_set_stop_bits(base, DASD_STOPPED_QUIESCE); 105 105 spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); 106 106 return 0; 107 107 } ··· 122 122 pr_info("%s: I/O operations have been resumed " 123 123 "on the DASD\n", dev_name(&base->cdev->dev)); 124 124 spin_lock_irqsave(get_ccwdev_lock(base->cdev), flags); 125 - base->stopped &= ~DASD_STOPPED_QUIESCE; 125 + dasd_device_remove_stop_bits(base, DASD_STOPPED_QUIESCE); 126 126 spin_unlock_irqrestore(get_ccwdev_lock(base->cdev), flags); 127 127 128 128 dasd_schedule_block_bh(block);
-1
drivers/s390/char/con3215.c
··· 857 857 858 858 /* 859 859 * 3215 console initialization code called from console_init(). 860 - * NOTE: This is called before kmalloc is available. 861 860 */ 862 861 static int __init con3215_init(void) 863 862 {
-1
drivers/s390/char/con3270.c
··· 572 572 573 573 /* 574 574 * 3270 console initialization code called from console_init(). 575 - * NOTE: This is called before kmalloc is available. 576 575 */ 577 576 static int __init 578 577 con3270_init(void)
+6 -4
drivers/s390/char/fs3270.c
··· 38 38 size_t rdbuf_size; /* size of data returned by RDBUF */ 39 39 }; 40 40 41 + static DEFINE_MUTEX(fs3270_mutex); 42 + 41 43 static void 42 44 fs3270_wake_up(struct raw3270_request *rq, void *data) 43 45 { ··· 330 328 if (!fp) 331 329 return -ENODEV; 332 330 rc = 0; 333 - lock_kernel(); 331 + mutex_lock(&fs3270_mutex); 334 332 switch (cmd) { 335 333 case TUBICMD: 336 334 fp->read_command = arg; ··· 356 354 rc = -EFAULT; 357 355 break; 358 356 } 359 - unlock_kernel(); 357 + mutex_unlock(&fs3270_mutex); 360 358 return rc; 361 359 } 362 360 ··· 439 437 minor = tty->index + RAW3270_FIRSTMINOR; 440 438 tty_kref_put(tty); 441 439 } 442 - lock_kernel(); 440 + mutex_lock(&fs3270_mutex); 443 441 /* Check if some other program is already using fullscreen mode. */ 444 442 fp = (struct fs3270 *) raw3270_find_view(&fs3270_fn, minor); 445 443 if (!IS_ERR(fp)) { ··· 480 478 } 481 479 filp->private_data = fp; 482 480 out: 483 - unlock_kernel(); 481 + mutex_unlock(&fs3270_mutex); 484 482 return rc; 485 483 } 486 484
+4 -4
drivers/s390/char/monreader.c
··· 12 12 #include <linux/module.h> 13 13 #include <linux/moduleparam.h> 14 14 #include <linux/init.h> 15 - #include <linux/smp_lock.h> 16 15 #include <linux/errno.h> 17 16 #include <linux/types.h> 18 17 #include <linux/kernel.h> ··· 282 283 /* 283 284 * only one user allowed 284 285 */ 285 - lock_kernel(); 286 286 rc = -EBUSY; 287 287 if (test_and_set_bit(MON_IN_USE, &mon_in_use)) 288 288 goto out; ··· 319 321 } 320 322 filp->private_data = monpriv; 321 323 dev_set_drvdata(monreader_device, monpriv); 322 - unlock_kernel(); 323 324 return nonseekable_open(inode, filp); 324 325 325 326 out_path: ··· 328 331 out_use: 329 332 clear_bit(MON_IN_USE, &mon_in_use); 330 333 out: 331 - unlock_kernel(); 332 334 return rc; 333 335 } 334 336 ··· 603 607 } 604 608 dcss_mkname(mon_dcss_name, &user_data_connect[8]); 605 609 610 + /* 611 + * misc_register() has to be the last action in module_init(), because 612 + * file operations will be available right after this. 613 + */ 606 614 rc = misc_register(&mon_dev); 607 615 if (rc < 0 ) 608 616 goto out;
+4 -3
drivers/s390/char/monwriter.c
··· 13 13 #include <linux/moduleparam.h> 14 14 #include <linux/init.h> 15 15 #include <linux/errno.h> 16 - #include <linux/smp_lock.h> 17 16 #include <linux/types.h> 18 17 #include <linux/kernel.h> 19 18 #include <linux/miscdevice.h> ··· 184 185 monpriv = kzalloc(sizeof(struct mon_private), GFP_KERNEL); 185 186 if (!monpriv) 186 187 return -ENOMEM; 187 - lock_kernel(); 188 188 INIT_LIST_HEAD(&monpriv->list); 189 189 monpriv->hdr_to_read = sizeof(monpriv->hdr); 190 190 mutex_init(&monpriv->thread_mutex); 191 191 filp->private_data = monpriv; 192 192 list_add_tail(&monpriv->priv_list, &mon_priv_list); 193 - unlock_kernel(); 194 193 return nonseekable_open(inode, filp); 195 194 } 196 195 ··· 361 364 goto out_driver; 362 365 } 363 366 367 + /* 368 + * misc_register() has to be the last action in module_init(), because 369 + * file operations will be available right after this. 370 + */ 364 371 rc = misc_register(&mon_dev); 365 372 if (rc) 366 373 goto out_device;
+1
drivers/s390/char/sclp_cmd.c
··· 84 84 do { 85 85 memset(sccb, 0, sizeof(*sccb)); 86 86 sccb->header.length = sizeof(*sccb); 87 + sccb->header.function_code = 0x80; 87 88 sccb->header.control_mask[2] = 0x80; 88 89 rc = sclp_cmd_sync_early(commands[i], sccb); 89 90 } while (rc == -EBUSY);
+6 -3
drivers/s390/char/tape.h
··· 212 212 struct tape_class_device * nt; 213 213 struct tape_class_device * rt; 214 214 215 + /* Device mutex to serialize tape commands. */ 216 + struct mutex mutex; 217 + 215 218 /* Device discipline information. */ 216 219 struct tape_discipline * discipline; 217 220 void * discdata; ··· 295 292 extern int tape_generic_probe(struct ccw_device *); 296 293 extern void tape_generic_remove(struct ccw_device *); 297 294 298 - extern struct tape_device *tape_get_device(int devindex); 299 - extern struct tape_device *tape_get_device_reference(struct tape_device *); 300 - extern struct tape_device *tape_put_device(struct tape_device *); 295 + extern struct tape_device *tape_find_device(int devindex); 296 + extern struct tape_device *tape_get_device(struct tape_device *); 297 + extern void tape_put_device(struct tape_device *); 301 298 302 299 /* Externals from tape_char.c */ 303 300 extern int tapechar_init(void);
+4 -4
drivers/s390/char/tape_34xx.c
··· 113 113 { 114 114 struct tape_34xx_work *p = 115 115 container_of(work, struct tape_34xx_work, work); 116 + struct tape_device *device = p->device; 116 117 117 118 switch(p->op) { 118 119 case TO_MSEN: 119 - tape_34xx_medium_sense(p->device); 120 + tape_34xx_medium_sense(device); 120 121 break; 121 122 default: 122 123 DBF_EVENT(3, "T34XX: internal error: unknown work\n"); 123 124 } 124 - 125 - p->device = tape_put_device(p->device); 125 + tape_put_device(device); 126 126 kfree(p); 127 127 } 128 128 ··· 136 136 137 137 INIT_WORK(&p->work, tape_34xx_work_handler); 138 138 139 - p->device = tape_get_device_reference(device); 139 + p->device = tape_get_device(device); 140 140 p->op = op; 141 141 142 142 schedule_work(&p->work);
+1 -1
drivers/s390/char/tape_3590.c
··· 608 608 609 609 INIT_WORK(&p->work, tape_3590_work_handler); 610 610 611 - p->device = tape_get_device_reference(device); 611 + p->device = tape_get_device(device); 612 612 p->op = op; 613 613 614 614 schedule_work(&p->work);
+9 -8
drivers/s390/char/tape_block.c
··· 54 54 .owner = THIS_MODULE, 55 55 .open = tapeblock_open, 56 56 .release = tapeblock_release, 57 - .locked_ioctl = tapeblock_ioctl, 57 + .ioctl = tapeblock_ioctl, 58 58 .media_changed = tapeblock_medium_changed, 59 59 .revalidate_disk = tapeblock_revalidate_disk, 60 60 }; ··· 239 239 disk->major = tapeblock_major; 240 240 disk->first_minor = device->first_minor; 241 241 disk->fops = &tapeblock_fops; 242 - disk->private_data = tape_get_device_reference(device); 242 + disk->private_data = tape_get_device(device); 243 243 disk->queue = blkdat->request_queue; 244 244 set_capacity(disk, 0); 245 245 sprintf(disk->disk_name, "btibm%d", ··· 247 247 248 248 blkdat->disk = disk; 249 249 blkdat->medium_changed = 1; 250 - blkdat->request_queue->queuedata = tape_get_device_reference(device); 250 + blkdat->request_queue->queuedata = tape_get_device(device); 251 251 252 252 add_disk(disk); 253 253 254 - tape_get_device_reference(device); 254 + tape_get_device(device); 255 255 INIT_WORK(&blkdat->requeue_task, tapeblock_requeue); 256 256 257 257 return 0; ··· 274 274 } 275 275 276 276 del_gendisk(device->blk_data.disk); 277 - device->blk_data.disk->private_data = 278 - tape_put_device(device->blk_data.disk->private_data); 277 + device->blk_data.disk->private_data = NULL; 278 + tape_put_device(device); 279 279 put_disk(device->blk_data.disk); 280 280 281 281 device->blk_data.disk = NULL; 282 282 cleanup_queue: 283 - device->blk_data.request_queue->queuedata = tape_put_device(device); 283 + device->blk_data.request_queue->queuedata = NULL; 284 + tape_put_device(device); 284 285 285 286 blk_cleanup_queue(device->blk_data.request_queue); 286 287 device->blk_data.request_queue = NULL; ··· 364 363 struct tape_device * device; 365 364 int rc; 366 365 367 - device = tape_get_device_reference(disk->private_data); 366 + device = tape_get_device(disk->private_data); 368 367 369 368 if (device->required_tapemarks) { 370 369 DBF_EVENT(2, "TBLOCK: missing tapemarks\n");
+28 -26
drivers/s390/char/tape_char.c
··· 33 33 static ssize_t tapechar_write(struct file *, const char __user *, size_t, loff_t *); 34 34 static int tapechar_open(struct inode *,struct file *); 35 35 static int tapechar_release(struct inode *,struct file *); 36 - static int tapechar_ioctl(struct inode *, struct file *, unsigned int, 37 - unsigned long); 36 + static long tapechar_ioctl(struct file *, unsigned int, unsigned long); 38 37 static long tapechar_compat_ioctl(struct file *, unsigned int, 39 38 unsigned long); 40 39 ··· 42 43 .owner = THIS_MODULE, 43 44 .read = tapechar_read, 44 45 .write = tapechar_write, 45 - .ioctl = tapechar_ioctl, 46 + .unlocked_ioctl = tapechar_ioctl, 46 47 .compat_ioctl = tapechar_compat_ioctl, 47 48 .open = tapechar_open, 48 49 .release = tapechar_release, ··· 169 170 if (rc == 0) { 170 171 rc = block_size - request->rescnt; 171 172 DBF_EVENT(6, "TCHAR:rbytes: %x\n", rc); 172 - filp->f_pos += rc; 173 173 /* Copy data from idal buffer to user space. */ 174 174 if (idal_buffer_to_user(device->char_data.idal_buf, 175 175 data, rc) != 0) ··· 236 238 break; 237 239 DBF_EVENT(6, "TCHAR:wbytes: %lx\n", 238 240 block_size - request->rescnt); 239 - filp->f_pos += block_size - request->rescnt; 240 241 written += block_size - request->rescnt; 241 242 if (request->rescnt != 0) 242 243 break; ··· 283 286 if (imajor(filp->f_path.dentry->d_inode) != tapechar_major) 284 287 return -ENODEV; 285 288 286 - lock_kernel(); 287 289 minor = iminor(filp->f_path.dentry->d_inode); 288 - device = tape_get_device(minor / TAPE_MINORS_PER_DEV); 290 + device = tape_find_device(minor / TAPE_MINORS_PER_DEV); 289 291 if (IS_ERR(device)) { 290 - DBF_EVENT(3, "TCHAR:open: tape_get_device() failed\n"); 291 - rc = PTR_ERR(device); 292 - goto out; 292 + DBF_EVENT(3, "TCHAR:open: tape_find_device() failed\n"); 293 + return PTR_ERR(device); 293 294 } 294 - 295 295 296 296 rc = tape_open(device); 297 297 if (rc == 0) { 298 298 filp->private_data = device; 299 - rc = nonseekable_open(inode, filp); 300 - } 301 - else 299 + nonseekable_open(inode, filp); 300 + } else 302 301 tape_put_device(device); 303 302 304 - out: 305 - unlock_kernel(); 306 303 return rc; 307 304 } 308 305 ··· 333 342 device->char_data.idal_buf = NULL; 334 343 } 335 344 tape_release(device); 336 - filp->private_data = tape_put_device(device); 345 + filp->private_data = NULL; 346 + tape_put_device(device); 337 347 338 348 return 0; 339 349 } ··· 343 351 * Tape device io controls. 344 352 */ 345 353 static int 346 - tapechar_ioctl(struct inode *inp, struct file *filp, 347 - unsigned int no, unsigned long data) 354 + __tapechar_ioctl(struct tape_device *device, 355 + unsigned int no, unsigned long data) 348 356 { 349 - struct tape_device *device; 350 357 int rc; 351 - 352 - DBF_EVENT(6, "TCHAR:ioct\n"); 353 - 354 - device = (struct tape_device *) filp->private_data; 355 358 356 359 if (no == MTIOCTOP) { 357 360 struct mtop op; ··· 440 453 } 441 454 442 455 static long 456 + tapechar_ioctl(struct file *filp, unsigned int no, unsigned long data) 457 + { 458 + struct tape_device *device; 459 + long rc; 460 + 461 + DBF_EVENT(6, "TCHAR:ioct\n"); 462 + 463 + device = (struct tape_device *) filp->private_data; 464 + mutex_lock(&device->mutex); 465 + rc = __tapechar_ioctl(device, no, data); 466 + mutex_unlock(&device->mutex); 467 + return rc; 468 + } 469 + 470 + static long 443 471 tapechar_compat_ioctl(struct file *filp, unsigned int no, unsigned long data) 444 472 { 445 473 struct tape_device *device = filp->private_data; 446 474 int rval = -ENOIOCTLCMD; 447 475 448 476 if (device->discipline->ioctl_fn) { 449 - lock_kernel(); 477 + mutex_lock(&device->mutex); 450 478 rval = device->discipline->ioctl_fn(device, no, data); 451 - unlock_kernel(); 479 + mutex_unlock(&device->mutex); 452 480 if (rval == -EINVAL) 453 481 rval = -ENOIOCTLCMD; 454 482 }
+32 -33
drivers/s390/char/tape_core.c
··· 492 492 kfree(device); 493 493 return ERR_PTR(-ENOMEM); 494 494 } 495 + mutex_init(&device->mutex); 495 496 INIT_LIST_HEAD(&device->req_queue); 496 497 INIT_LIST_HEAD(&device->node); 497 498 init_waitqueue_head(&device->state_change_wq); ··· 512 511 * increment the reference count. 513 512 */ 514 513 struct tape_device * 515 - tape_get_device_reference(struct tape_device *device) 514 + tape_get_device(struct tape_device *device) 516 515 { 517 - DBF_EVENT(4, "tape_get_device_reference(%p) = %i\n", device, 518 - atomic_inc_return(&device->ref_count)); 516 + int count; 519 517 518 + count = atomic_inc_return(&device->ref_count); 519 + DBF_EVENT(4, "tape_get_device(%p) = %i\n", device, count); 520 520 return device; 521 521 } 522 522 ··· 527 525 * The function returns a NULL pointer to be used by the caller 528 526 * for clearing reference pointers. 529 527 */ 530 - struct tape_device * 528 + void 531 529 tape_put_device(struct tape_device *device) 532 530 { 533 - int remain; 531 + int count; 534 532 535 - remain = atomic_dec_return(&device->ref_count); 536 - if (remain > 0) { 537 - DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, remain); 538 - } else { 539 - if (remain < 0) { 540 - DBF_EVENT(4, "put device without reference\n"); 541 - } else { 542 - DBF_EVENT(4, "tape_free_device(%p)\n", device); 543 - kfree(device->modeset_byte); 544 - kfree(device); 545 - } 533 + count = atomic_dec_return(&device->ref_count); 534 + DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, count); 535 + BUG_ON(count < 0); 536 + if (count == 0) { 537 + kfree(device->modeset_byte); 538 + kfree(device); 546 539 } 547 - 548 - return NULL; 549 540 } 550 541 551 542 /* 552 543 * Find tape device by a device index. 553 544 */ 554 545 struct tape_device * 555 - tape_get_device(int devindex) 546 + tape_find_device(int devindex) 556 547 { 557 548 struct tape_device *device, *tmp; 558 549 ··· 553 558 read_lock(&tape_device_lock); 554 559 list_for_each_entry(tmp, &tape_device_list, node) { 555 560 if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) { 556 - device = tape_get_device_reference(tmp); 561 + device = tape_get_device(tmp); 557 562 break; 558 563 } 559 564 } ··· 574 579 device = tape_alloc_device(); 575 580 if (IS_ERR(device)) 576 581 return -ENODEV; 577 - ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); 582 + ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | 583 + CCWDEV_DO_MULTIPATH); 578 584 ret = sysfs_create_group(&cdev->dev.kobj, &tape_attr_group); 579 585 if (ret) { 580 586 tape_put_device(device); ··· 602 606 list_del(&request->list); 603 607 604 608 /* Decrease ref_count for removed request. */ 605 - request->device = tape_put_device(device); 609 + request->device = NULL; 610 + tape_put_device(device); 606 611 request->rc = -EIO; 607 612 if (request->callback != NULL) 608 613 request->callback(request, request->callback_data); ··· 661 664 tape_cleanup_device(device); 662 665 } 663 666 664 - if (!dev_get_drvdata(&cdev->dev)) { 667 + device = dev_get_drvdata(&cdev->dev); 668 + if (device) { 665 669 sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group); 666 - dev_set_drvdata(&cdev->dev, tape_put_device(dev_get_drvdata(&cdev->dev))); 670 + dev_set_drvdata(&cdev->dev, NULL); 671 + tape_put_device(device); 667 672 } 668 673 } 669 674 ··· 720 721 { 721 722 DBF_LH(6, "Free request %p\n", request); 722 723 723 - if (request->device != NULL) { 724 - request->device = tape_put_device(request->device); 725 - } 724 + if (request->device) 725 + tape_put_device(request->device); 726 726 kfree(request->cpdata); 727 727 kfree(request->cpaddr); 728 728 kfree(request); ··· 836 838 BUG_ON(request->status != TAPE_REQUEST_LONG_BUSY); 837 839 DBF_LH(6, "%08x: Long busy timeout.\n", device->cdev_id); 838 840 __tape_start_next_request(device); 839 - device->lb_timeout.data = (unsigned long) tape_put_device(device); 841 + device->lb_timeout.data = 0UL; 842 + tape_put_device(device); 840 843 spin_unlock_irq(get_ccwdev_lock(device->cdev)); 841 844 } 842 845 ··· 917 918 } 918 919 919 920 /* Increase use count of device for the added request. */ 920 - request->device = tape_get_device_reference(device); 921 + request->device = tape_get_device(device); 921 922 922 923 if (list_empty(&device->req_queue)) { 923 924 /* No other requests are on the queue. Start this one. */ ··· 1116 1117 if (req->status == TAPE_REQUEST_LONG_BUSY) { 1117 1118 DBF_EVENT(3, "(%08x): del timer\n", device->cdev_id); 1118 1119 if (del_timer(&device->lb_timeout)) { 1119 - device->lb_timeout.data = (unsigned long) 1120 - tape_put_device(device); 1120 + device->lb_timeout.data = 0UL; 1121 + tape_put_device(device); 1121 1122 __tape_start_next_request(device); 1122 1123 } 1123 1124 return; ··· 1172 1173 break; 1173 1174 case TAPE_IO_LONG_BUSY: 1174 1175 device->lb_timeout.data = 1175 - (unsigned long)tape_get_device_reference(device); 1176 + (unsigned long) tape_get_device(device); 1176 1177 device->lb_timeout.expires = jiffies + 1177 1178 LONG_BUSY_TIMEOUT * HZ; 1178 1179 DBF_EVENT(3, "(%08x): add timer\n", device->cdev_id); ··· 1325 1326 EXPORT_SYMBOL(tape_generic_offline); 1326 1327 EXPORT_SYMBOL(tape_generic_pm_suspend); 1327 1328 EXPORT_SYMBOL(tape_put_device); 1328 - EXPORT_SYMBOL(tape_get_device_reference); 1329 + EXPORT_SYMBOL(tape_get_device); 1329 1330 EXPORT_SYMBOL(tape_state_verbose); 1330 1331 EXPORT_SYMBOL(tape_op_verbose); 1331 1332 EXPORT_SYMBOL(tape_state_set);
+1 -1
drivers/s390/char/tape_proc.c
··· 45 45 seq_printf(m, "TapeNo\tBusID CuType/Model\t" 46 46 "DevType/Model\tBlkSize\tState\tOp\tMedState\n"); 47 47 } 48 - device = tape_get_device(n); 48 + device = tape_find_device(n); 49 49 if (IS_ERR(device)) 50 50 return 0; 51 51 spin_lock_irq(get_ccwdev_lock(device->cdev));
+20
drivers/s390/char/tty3270.c
··· 19 19 20 20 #include <linux/slab.h> 21 21 #include <linux/bootmem.h> 22 + #include <linux/compat.h> 22 23 23 24 #include <asm/ccwdev.h> 24 25 #include <asm/cio.h> ··· 1732 1731 return kbd_ioctl(tp->kbd, file, cmd, arg); 1733 1732 } 1734 1733 1734 + #ifdef CONFIG_COMPAT 1735 + static long 1736 + tty3270_compat_ioctl(struct tty_struct *tty, struct file *file, 1737 + unsigned int cmd, unsigned long arg) 1738 + { 1739 + struct tty3270 *tp; 1740 + 1741 + tp = tty->driver_data; 1742 + if (!tp) 1743 + return -ENODEV; 1744 + if (tty->flags & (1 << TTY_IO_ERROR)) 1745 + return -EIO; 1746 + return kbd_ioctl(tp->kbd, file, cmd, (unsigned long)compat_ptr(arg)); 1747 + } 1748 + #endif 1749 + 1735 1750 static const struct tty_operations tty3270_ops = { 1736 1751 .open = tty3270_open, 1737 1752 .close = tty3270_close, ··· 1762 1745 .hangup = tty3270_hangup, 1763 1746 .wait_until_sent = tty3270_wait_until_sent, 1764 1747 .ioctl = tty3270_ioctl, 1748 + #ifdef CONFIG_COMPAT 1749 + .compat_ioctl = tty3270_compat_ioctl, 1750 + #endif 1765 1751 .set_termios = tty3270_set_termios 1766 1752 }; 1767 1753
+2 -6
drivers/s390/char/vmlogrdr.c
··· 312 312 return -ENOSYS; 313 313 314 314 /* Besure this device hasn't already been opened */ 315 - lock_kernel(); 316 315 spin_lock_bh(&logptr->priv_lock); 317 316 if (logptr->dev_in_use) { 318 317 spin_unlock_bh(&logptr->priv_lock); 319 - unlock_kernel(); 320 318 return -EBUSY; 321 319 } 322 320 logptr->dev_in_use = 1; ··· 358 360 || (logptr->iucv_path_severed)); 359 361 if (logptr->iucv_path_severed) 360 362 goto out_record; 361 - ret = nonseekable_open(inode, filp); 362 - unlock_kernel(); 363 - return ret; 363 + nonseekable_open(inode, filp); 364 + return 0; 364 365 365 366 out_record: 366 367 if (logptr->autorecording) ··· 369 372 logptr->path = NULL; 370 373 out_dev: 371 374 logptr->dev_in_use = 0; 372 - unlock_kernel(); 373 375 return -EIO; 374 376 } 375 377
-3
drivers/s390/char/vmur.c
··· 695 695 696 696 if (accmode == O_RDWR) 697 697 return -EACCES; 698 - lock_kernel(); 699 698 /* 700 699 * We treat the minor number as the devno of the ur device 701 700 * to find in the driver tree. ··· 748 749 goto fail_urfile_free; 749 750 urf->file_reclen = rc; 750 751 file->private_data = urf; 751 - unlock_kernel(); 752 752 return 0; 753 753 754 754 fail_urfile_free: ··· 759 761 fail_put: 760 762 urdev_put(urd); 761 763 out: 762 - unlock_kernel(); 763 764 return rc; 764 765 } 765 766
+19 -10
drivers/s390/char/vmwatchdog.c
··· 19 19 #include <linux/moduleparam.h> 20 20 #include <linux/suspend.h> 21 21 #include <linux/watchdog.h> 22 - #include <linux/smp_lock.h> 23 22 24 23 #include <asm/ebcdic.h> 25 24 #include <asm/io.h> ··· 47 48 static unsigned int vmwdt_interval = 60; 48 49 static unsigned long vmwdt_is_open; 49 50 static int vmwdt_expect_close; 51 + 52 + static DEFINE_MUTEX(vmwdt_mutex); 50 53 51 54 #define VMWDT_OPEN 0 /* devnode is open or suspend in progress */ 52 55 #define VMWDT_RUNNING 1 /* The watchdog is armed */ ··· 134 133 static int vmwdt_open(struct inode *i, struct file *f) 135 134 { 136 135 int ret; 137 - lock_kernel(); 138 - if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) { 139 - unlock_kernel(); 136 + if (test_and_set_bit(VMWDT_OPEN, &vmwdt_is_open)) 140 137 return -EBUSY; 141 - } 142 138 ret = vmwdt_keepalive(); 143 139 if (ret) 144 140 clear_bit(VMWDT_OPEN, &vmwdt_is_open); 145 - unlock_kernel(); 146 141 return ret ? ret : nonseekable_open(i, f); 147 142 } 148 143 ··· 157 160 .identity = "z/VM Watchdog Timer", 158 161 }; 159 162 160 - static int vmwdt_ioctl(struct inode *i, struct file *f, 161 - unsigned int cmd, unsigned long arg) 163 + static int __vmwdt_ioctl(unsigned int cmd, unsigned long arg) 162 164 { 163 165 switch (cmd) { 164 166 case WDIOC_GETSUPPORT: ··· 201 205 case WDIOC_KEEPALIVE: 202 206 return vmwdt_keepalive(); 203 207 } 204 - 205 208 return -EINVAL; 209 + } 210 + 211 + static long vmwdt_ioctl(struct file *f, unsigned int cmd, unsigned long arg) 212 + { 213 + int rc; 214 + 215 + mutex_lock(&vmwdt_mutex); 216 + rc = __vmwdt_ioctl(cmd, arg); 217 + mutex_unlock(&vmwdt_mutex); 218 + return (long) rc; 206 219 } 207 220 208 221 static ssize_t vmwdt_write(struct file *f, const char __user *buf, ··· 293 288 static const struct file_operations vmwdt_fops = { 294 289 .open = &vmwdt_open, 295 290 .release = &vmwdt_close, 296 - .ioctl = &vmwdt_ioctl, 291 + .unlocked_ioctl = &vmwdt_ioctl, 297 292 .write = &vmwdt_write, 298 293 .owner = THIS_MODULE, 299 294 }; ··· 314 309 ret = register_pm_notifier(&vmwdt_power_notifier); 315 310 if (ret) 316 311 return ret; 312 + /* 313 + * misc_register() has to be the last action in module_init(), because 314 + * file operations will be available right after this. 315 + */ 317 316 ret = misc_register(&vmwdt_dev); 318 317 if (ret) { 319 318 unregister_pm_notifier(&vmwdt_power_notifier);
+1 -1
drivers/s390/cio/Makefile
··· 3 3 # 4 4 5 5 obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \ 6 - fcx.o itcw.o crw.o 6 + fcx.o itcw.o crw.o ccwreq.o 7 7 ccw_device-objs += device.o device_fsm.o device_ops.o 8 8 ccw_device-objs += device_id.o device_pgid.o device_status.o 9 9 obj-y += ccw_device.o cmf.o
+328
drivers/s390/cio/ccwreq.c
··· 1 + /* 2 + * Handling of internal CCW device requests. 3 + * 4 + * Copyright IBM Corp. 2009 5 + * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> 6 + */ 7 + 8 + #include <linux/types.h> 9 + #include <linux/err.h> 10 + #include <asm/ccwdev.h> 11 + #include <asm/cio.h> 12 + 13 + #include "io_sch.h" 14 + #include "cio.h" 15 + #include "device.h" 16 + #include "cio_debug.h" 17 + 18 + /** 19 + * lpm_adjust - adjust path mask 20 + * @lpm: path mask to adjust 21 + * @mask: mask of available paths 22 + * 23 + * Shift @lpm right until @lpm and @mask have at least one bit in common or 24 + * until @lpm is zero. Return the resulting lpm. 25 + */ 26 + int lpm_adjust(int lpm, int mask) 27 + { 28 + while (lpm && ((lpm & mask) == 0)) 29 + lpm >>= 1; 30 + return lpm; 31 + } 32 + 33 + /* 34 + * Adjust path mask to use next path and reset retry count. Return resulting 35 + * path mask. 36 + */ 37 + static u16 ccwreq_next_path(struct ccw_device *cdev) 38 + { 39 + struct ccw_request *req = &cdev->private->req; 40 + 41 + req->retries = req->maxretries; 42 + req->mask = lpm_adjust(req->mask >>= 1, req->lpm); 43 + 44 + return req->mask; 45 + } 46 + 47 + /* 48 + * Clean up device state and report to callback. 49 + */ 50 + static void ccwreq_stop(struct ccw_device *cdev, int rc) 51 + { 52 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 53 + struct ccw_request *req = &cdev->private->req; 54 + 55 + if (req->done) 56 + return; 57 + req->done = 1; 58 + ccw_device_set_timeout(cdev, 0); 59 + memset(&cdev->private->irb, 0, sizeof(struct irb)); 60 + sch->lpm = sch->schib.pmcw.pam; 61 + if (rc && rc != -ENODEV && req->drc) 62 + rc = req->drc; 63 + req->callback(cdev, req->data, rc); 64 + } 65 + 66 + /* 67 + * (Re-)Start the operation until retries and paths are exhausted. 68 + */ 69 + static void ccwreq_do(struct ccw_device *cdev) 70 + { 71 + struct ccw_request *req = &cdev->private->req; 72 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 73 + struct ccw1 *cp = req->cp; 74 + int rc = -EACCES; 75 + 76 + while (req->mask) { 77 + if (req->retries-- == 0) { 78 + /* Retries exhausted, try next path. */ 79 + ccwreq_next_path(cdev); 80 + continue; 81 + } 82 + /* Perform start function. */ 83 + sch->lpm = 0xff; 84 + memset(&cdev->private->irb, 0, sizeof(struct irb)); 85 + rc = cio_start(sch, cp, (u8) req->mask); 86 + if (rc == 0) { 87 + /* I/O started successfully. */ 88 + ccw_device_set_timeout(cdev, req->timeout); 89 + return; 90 + } 91 + if (rc == -ENODEV) { 92 + /* Permanent device error. */ 93 + break; 94 + } 95 + if (rc == -EACCES) { 96 + /* Permant path error. */ 97 + ccwreq_next_path(cdev); 98 + continue; 99 + } 100 + /* Temporary improper status. */ 101 + rc = cio_clear(sch); 102 + if (rc) 103 + break; 104 + return; 105 + } 106 + ccwreq_stop(cdev, rc); 107 + } 108 + 109 + /** 110 + * ccw_request_start - perform I/O request 111 + * @cdev: ccw device 112 + * 113 + * Perform the I/O request specified by cdev->req. 114 + */ 115 + void ccw_request_start(struct ccw_device *cdev) 116 + { 117 + struct ccw_request *req = &cdev->private->req; 118 + 119 + /* Try all paths twice to counter link flapping. */ 120 + req->mask = 0x8080; 121 + req->retries = req->maxretries; 122 + req->mask = lpm_adjust(req->mask, req->lpm); 123 + req->drc = 0; 124 + req->done = 0; 125 + req->cancel = 0; 126 + if (!req->mask) 127 + goto out_nopath; 128 + ccwreq_do(cdev); 129 + return; 130 + 131 + out_nopath: 132 + ccwreq_stop(cdev, -EACCES); 133 + } 134 + 135 + /** 136 + * ccw_request_cancel - cancel running I/O request 137 + * @cdev: ccw device 138 + * 139 + * Cancel the I/O request specified by cdev->req. Return non-zero if request 140 + * has already finished, zero otherwise. 141 + */ 142 + int ccw_request_cancel(struct ccw_device *cdev) 143 + { 144 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 145 + struct ccw_request *req = &cdev->private->req; 146 + int rc; 147 + 148 + if (req->done) 149 + return 1; 150 + req->cancel = 1; 151 + rc = cio_clear(sch); 152 + if (rc) 153 + ccwreq_stop(cdev, rc); 154 + return 0; 155 + } 156 + 157 + /* 158 + * Return the status of the internal I/O started on the specified ccw device. 159 + * Perform BASIC SENSE if required. 160 + */ 161 + static enum io_status ccwreq_status(struct ccw_device *cdev, struct irb *lcirb) 162 + { 163 + struct irb *irb = &cdev->private->irb; 164 + struct cmd_scsw *scsw = &irb->scsw.cmd; 165 + 166 + /* Perform BASIC SENSE if needed. */ 167 + if (ccw_device_accumulate_and_sense(cdev, lcirb)) 168 + return IO_RUNNING; 169 + /* Check for halt/clear interrupt. */ 170 + if (scsw->fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) 171 + return IO_KILLED; 172 + /* Check for path error. */ 173 + if (scsw->cc == 3 || scsw->pno) 174 + return IO_PATH_ERROR; 175 + /* Handle BASIC SENSE data. */ 176 + if (irb->esw.esw0.erw.cons) { 177 + CIO_TRACE_EVENT(2, "sensedata"); 178 + CIO_HEX_EVENT(2, &cdev->private->dev_id, 179 + sizeof(struct ccw_dev_id)); 180 + CIO_HEX_EVENT(2, &cdev->private->irb.ecw, SENSE_MAX_COUNT); 181 + /* Check for command reject. */ 182 + if (irb->ecw[0] & SNS0_CMD_REJECT) 183 + return IO_REJECTED; 184 + /* Assume that unexpected SENSE data implies an error. */ 185 + return IO_STATUS_ERROR; 186 + } 187 + /* Check for channel errors. */ 188 + if (scsw->cstat != 0) 189 + return IO_STATUS_ERROR; 190 + /* Check for device errors. */ 191 + if (scsw->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) 192 + return IO_STATUS_ERROR; 193 + /* Check for final state. */ 194 + if (!(scsw->dstat & DEV_STAT_DEV_END)) 195 + return IO_RUNNING; 196 + /* Check for other improper status. */ 197 + if (scsw->cc == 1 && (scsw->stctl & SCSW_STCTL_ALERT_STATUS)) 198 + return IO_STATUS_ERROR; 199 + return IO_DONE; 200 + } 201 + 202 + /* 203 + * Log ccw request status. 204 + */ 205 + static void ccwreq_log_status(struct ccw_device *cdev, enum io_status status) 206 + { 207 + struct ccw_request *req = &cdev->private->req; 208 + struct { 209 + struct ccw_dev_id dev_id; 210 + u16 retries; 211 + u8 lpm; 212 + u8 status; 213 + } __attribute__ ((packed)) data; 214 + data.dev_id = cdev->private->dev_id; 215 + data.retries = req->retries; 216 + data.lpm = (u8) req->mask; 217 + data.status = (u8) status; 218 + CIO_TRACE_EVENT(2, "reqstat"); 219 + CIO_HEX_EVENT(2, &data, sizeof(data)); 220 + } 221 + 222 + /** 223 + * ccw_request_handler - interrupt handler for I/O request procedure. 224 + * @cdev: ccw device 225 + * 226 + * Handle interrupt during I/O request procedure. 227 + */ 228 + void ccw_request_handler(struct ccw_device *cdev) 229 + { 230 + struct ccw_request *req = &cdev->private->req; 231 + struct irb *irb = (struct irb *) __LC_IRB; 232 + enum io_status status; 233 + int rc = -EOPNOTSUPP; 234 + 235 + /* Check status of I/O request. */ 236 + status = ccwreq_status(cdev, irb); 237 + if (req->filter) 238 + status = req->filter(cdev, req->data, irb, status); 239 + if (status != IO_RUNNING) 240 + ccw_device_set_timeout(cdev, 0); 241 + if (status != IO_DONE && status != IO_RUNNING) 242 + ccwreq_log_status(cdev, status); 243 + switch (status) { 244 + case IO_DONE: 245 + break; 246 + case IO_RUNNING: 247 + return; 248 + case IO_REJECTED: 249 + goto err; 250 + case IO_PATH_ERROR: 251 + goto out_next_path; 252 + case IO_STATUS_ERROR: 253 + goto out_restart; 254 + case IO_KILLED: 255 + /* Check if request was cancelled on purpose. */ 256 + if (req->cancel) { 257 + rc = -EIO; 258 + goto err; 259 + } 260 + goto out_restart; 261 + } 262 + /* Check back with request initiator. */ 263 + if (!req->check) 264 + goto out; 265 + switch (req->check(cdev, req->data)) { 266 + case 0: 267 + break; 268 + case -EAGAIN: 269 + goto out_restart; 270 + case -EACCES: 271 + goto out_next_path; 272 + default: 273 + goto err; 274 + } 275 + out: 276 + ccwreq_stop(cdev, 0); 277 + return; 278 + 279 + out_next_path: 280 + /* Try next path and restart I/O. */ 281 + if (!ccwreq_next_path(cdev)) { 282 + rc = -EACCES; 283 + goto err; 284 + } 285 + out_restart: 286 + /* Restart. */ 287 + ccwreq_do(cdev); 288 + return; 289 + err: 290 + ccwreq_stop(cdev, rc); 291 + } 292 + 293 + 294 + /** 295 + * ccw_request_timeout - timeout handler for I/O request procedure 296 + * @cdev: ccw device 297 + * 298 + * Handle timeout during I/O request procedure. 299 + */ 300 + void ccw_request_timeout(struct ccw_device *cdev) 301 + { 302 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 303 + struct ccw_request *req = &cdev->private->req; 304 + int rc; 305 + 306 + if (!ccwreq_next_path(cdev)) { 307 + /* set the final return code for this request */ 308 + req->drc = -ETIME; 309 + } 310 + rc = cio_clear(sch); 311 + if (rc) 312 + goto err; 313 + return; 314 + 315 + err: 316 + ccwreq_stop(cdev, rc); 317 + } 318 + 319 + /** 320 + * ccw_request_notoper - notoper handler for I/O request procedure 321 + * @cdev: ccw device 322 + * 323 + * Handle timeout during I/O request procedure. 324 + */ 325 + void ccw_request_notoper(struct ccw_device *cdev) 326 + { 327 + ccwreq_stop(cdev, -ENODEV); 328 + }
+7 -1
drivers/s390/cio/cio.h
··· 68 68 __u8 mda[4]; /* model dependent area */ 69 69 } __attribute__ ((packed,aligned(4))); 70 70 71 + enum sch_todo { 72 + SCH_TODO_NOTHING, 73 + SCH_TODO_UNREG, 74 + }; 75 + 71 76 /* subchannel data structure used by I/O subroutines */ 72 77 struct subchannel { 73 78 struct subchannel_id schid; ··· 100 95 struct device dev; /* entry in device tree */ 101 96 struct css_driver *driver; 102 97 void *private; /* private per subchannel type data */ 103 - struct work_struct work; 98 + enum sch_todo todo; 99 + struct work_struct todo_work; 104 100 struct schib_config config; 105 101 } __attribute__ ((aligned(8))); 106 102
+55 -2
drivers/s390/cio/css.c
··· 133 133 return rc; 134 134 } 135 135 136 + static void css_sch_todo(struct work_struct *work); 137 + 136 138 static struct subchannel * 137 139 css_alloc_subchannel(struct subchannel_id schid) 138 140 { ··· 149 147 kfree(sch); 150 148 return ERR_PTR(ret); 151 149 } 150 + INIT_WORK(&sch->todo_work, css_sch_todo); 152 151 return sch; 153 152 } 154 153 ··· 192 189 mutex_unlock(&sch->reg_mutex); 193 190 } 194 191 EXPORT_SYMBOL_GPL(css_sch_device_unregister); 192 + 193 + static void css_sch_todo(struct work_struct *work) 194 + { 195 + struct subchannel *sch; 196 + enum sch_todo todo; 197 + 198 + sch = container_of(work, struct subchannel, todo_work); 199 + /* Find out todo. */ 200 + spin_lock_irq(sch->lock); 201 + todo = sch->todo; 202 + CIO_MSG_EVENT(4, "sch_todo: sch=0.%x.%04x, todo=%d\n", sch->schid.ssid, 203 + sch->schid.sch_no, todo); 204 + sch->todo = SCH_TODO_NOTHING; 205 + spin_unlock_irq(sch->lock); 206 + /* Perform todo. */ 207 + if (todo == SCH_TODO_UNREG) 208 + css_sch_device_unregister(sch); 209 + /* Release workqueue ref. */ 210 + put_device(&sch->dev); 211 + } 212 + 213 + /** 214 + * css_sched_sch_todo - schedule a subchannel operation 215 + * @sch: subchannel 216 + * @todo: todo 217 + * 218 + * Schedule the operation identified by @todo to be performed on the slow path 219 + * workqueue. Do nothing if another operation with higher priority is already 220 + * scheduled. Needs to be called with subchannel lock held. 221 + */ 222 + void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo) 223 + { 224 + CIO_MSG_EVENT(4, "sch_todo: sched sch=0.%x.%04x todo=%d\n", 225 + sch->schid.ssid, sch->schid.sch_no, todo); 226 + if (sch->todo >= todo) 227 + return; 228 + /* Get workqueue ref. */ 229 + if (!get_device(&sch->dev)) 230 + return; 231 + sch->todo = todo; 232 + if (!queue_work(slow_path_wq, &sch->todo_work)) { 233 + /* Already queued, release workqueue ref. */ 234 + put_device(&sch->dev); 235 + } 236 + } 195 237 196 238 static void ssd_from_pmcw(struct chsc_ssd_info *ssd, struct pmcw *pmcw) 197 239 { ··· 424 376 /* Unusable - ignore. */ 425 377 return 0; 426 378 } 427 - CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, unknown, " 428 - "slow path.\n", schid.ssid, schid.sch_no, CIO_OPER); 379 + CIO_MSG_EVENT(4, "event: sch 0.%x.%04x, new\n", schid.ssid, 380 + schid.sch_no); 429 381 430 382 return css_probe_device(schid); 431 383 } ··· 441 393 dev_dbg(&sch->dev, 442 394 "Got subchannel machine check but " 443 395 "no sch_event handler provided.\n"); 396 + } 397 + if (ret != 0 && ret != -EAGAIN) { 398 + CIO_MSG_EVENT(2, "eval: sch 0.%x.%04x, rc=%d\n", 399 + sch->schid.ssid, sch->schid.sch_no, ret); 444 400 } 445 401 return ret; 446 402 } ··· 736 684 css->pseudo_subchannel->dev.parent = &css->device; 737 685 css->pseudo_subchannel->dev.release = css_subchannel_release; 738 686 dev_set_name(&css->pseudo_subchannel->dev, "defunct"); 687 + mutex_init(&css->pseudo_subchannel->reg_mutex); 739 688 ret = cio_create_sch_lock(css->pseudo_subchannel); 740 689 if (ret) { 741 690 kfree(css->pseudo_subchannel);
+3
drivers/s390/cio/css.h
··· 11 11 #include <asm/chpid.h> 12 12 #include <asm/schid.h> 13 13 14 + #include "cio.h" 15 + 14 16 /* 15 17 * path grouping stuff 16 18 */ ··· 153 151 154 152 extern struct workqueue_struct *slow_path_wq; 155 153 void css_wait_for_slow_path(void); 154 + void css_sched_sch_todo(struct subchannel *sch, enum sch_todo todo); 156 155 #endif
+421 -593
drivers/s390/cio/device.c
··· 7 7 * Cornelia Huck (cornelia.huck@de.ibm.com) 8 8 * Martin Schwidefsky (schwidefsky@de.ibm.com) 9 9 */ 10 + 11 + #define KMSG_COMPONENT "cio" 12 + #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 13 + 10 14 #include <linux/module.h> 11 15 #include <linux/init.h> 12 16 #include <linux/spinlock.h> ··· 303 299 304 300 static void ccw_device_unregister(struct ccw_device *cdev) 305 301 { 306 - if (test_and_clear_bit(1, &cdev->private->registered)) { 302 + if (device_is_registered(&cdev->dev)) { 303 + /* Undo device_add(). */ 307 304 device_del(&cdev->dev); 305 + } 306 + if (cdev->private->flags.initialized) { 307 + cdev->private->flags.initialized = 0; 308 308 /* Release reference from device_initialize(). */ 309 309 put_device(&cdev->dev); 310 310 } 311 311 } 312 312 313 - static void ccw_device_remove_orphan_cb(struct work_struct *work) 314 - { 315 - struct ccw_device_private *priv; 316 - struct ccw_device *cdev; 317 - 318 - priv = container_of(work, struct ccw_device_private, kick_work); 319 - cdev = priv->cdev; 320 - ccw_device_unregister(cdev); 321 - /* Release cdev reference for workqueue processing. */ 322 - put_device(&cdev->dev); 323 - } 324 - 325 - static void 326 - ccw_device_remove_disconnected(struct ccw_device *cdev) 327 - { 328 - unsigned long flags; 329 - 330 - /* 331 - * Forced offline in disconnected state means 332 - * 'throw away device'. 333 - */ 334 - if (ccw_device_is_orphan(cdev)) { 335 - /* 336 - * Deregister ccw device. 337 - * Unfortunately, we cannot do this directly from the 338 - * attribute method. 339 - */ 340 - /* Get cdev reference for workqueue processing. */ 341 - if (!get_device(&cdev->dev)) 342 - return; 343 - spin_lock_irqsave(cdev->ccwlock, flags); 344 - cdev->private->state = DEV_STATE_NOT_OPER; 345 - spin_unlock_irqrestore(cdev->ccwlock, flags); 346 - PREPARE_WORK(&cdev->private->kick_work, 347 - ccw_device_remove_orphan_cb); 348 - queue_work(slow_path_wq, &cdev->private->kick_work); 349 - } else 350 - /* Deregister subchannel, which will kill the ccw device. */ 351 - ccw_device_schedule_sch_unregister(cdev); 352 - } 313 + static void io_subchannel_quiesce(struct subchannel *); 353 314 354 315 /** 355 316 * ccw_device_set_offline() - disable a ccw device for I/O ··· 329 360 */ 330 361 int ccw_device_set_offline(struct ccw_device *cdev) 331 362 { 332 - int ret; 363 + struct subchannel *sch; 364 + int ret, state; 333 365 334 366 if (!cdev) 335 367 return -ENODEV; ··· 344 374 } 345 375 cdev->online = 0; 346 376 spin_lock_irq(cdev->ccwlock); 377 + sch = to_subchannel(cdev->dev.parent); 347 378 /* Wait until a final state or DISCONNECTED is reached */ 348 379 while (!dev_fsm_final_state(cdev) && 349 380 cdev->private->state != DEV_STATE_DISCONNECTED) { ··· 353 382 cdev->private->state == DEV_STATE_DISCONNECTED)); 354 383 spin_lock_irq(cdev->ccwlock); 355 384 } 356 - ret = ccw_device_offline(cdev); 357 - if (ret) 358 - goto error; 385 + do { 386 + ret = ccw_device_offline(cdev); 387 + if (!ret) 388 + break; 389 + CIO_MSG_EVENT(0, "ccw_device_offline returned %d, device " 390 + "0.%x.%04x\n", ret, cdev->private->dev_id.ssid, 391 + cdev->private->dev_id.devno); 392 + if (ret != -EBUSY) 393 + goto error; 394 + state = cdev->private->state; 395 + spin_unlock_irq(cdev->ccwlock); 396 + io_subchannel_quiesce(sch); 397 + spin_lock_irq(cdev->ccwlock); 398 + cdev->private->state = state; 399 + } while (ret == -EBUSY); 359 400 spin_unlock_irq(cdev->ccwlock); 360 401 wait_event(cdev->private->wait_q, (dev_fsm_final_state(cdev) || 361 402 cdev->private->state == DEV_STATE_DISCONNECTED)); 403 + /* Inform the user if set offline failed. */ 404 + if (cdev->private->state == DEV_STATE_BOXED) { 405 + pr_warning("%s: The device entered boxed state while " 406 + "being set offline\n", dev_name(&cdev->dev)); 407 + } else if (cdev->private->state == DEV_STATE_NOT_OPER) { 408 + pr_warning("%s: The device stopped operating while " 409 + "being set offline\n", dev_name(&cdev->dev)); 410 + } 362 411 /* Give up reference from ccw_device_set_online(). */ 363 412 put_device(&cdev->dev); 364 413 return 0; 365 414 366 415 error: 367 - CIO_MSG_EVENT(0, "ccw_device_offline returned %d, device 0.%x.%04x\n", 368 - ret, cdev->private->dev_id.ssid, 369 - cdev->private->dev_id.devno); 370 416 cdev->private->state = DEV_STATE_OFFLINE; 371 417 dev_fsm_event(cdev, DEV_EVENT_NOTOPER); 372 418 spin_unlock_irq(cdev->ccwlock); ··· 436 448 if ((cdev->private->state != DEV_STATE_ONLINE) && 437 449 (cdev->private->state != DEV_STATE_W4SENSE)) { 438 450 spin_unlock_irq(cdev->ccwlock); 451 + /* Inform the user that set online failed. */ 452 + if (cdev->private->state == DEV_STATE_BOXED) { 453 + pr_warning("%s: Setting the device online failed " 454 + "because it is boxed\n", 455 + dev_name(&cdev->dev)); 456 + } else if (cdev->private->state == DEV_STATE_NOT_OPER) { 457 + pr_warning("%s: Setting the device online failed " 458 + "because it is not operational\n", 459 + dev_name(&cdev->dev)); 460 + } 439 461 /* Give up online reference since onlining failed. */ 440 462 put_device(&cdev->dev); 441 463 return -ENODEV; ··· 492 494 493 495 static int online_store_handle_offline(struct ccw_device *cdev) 494 496 { 495 - if (cdev->private->state == DEV_STATE_DISCONNECTED) 496 - ccw_device_remove_disconnected(cdev); 497 - else if (cdev->online && cdev->drv && cdev->drv->set_offline) 497 + if (cdev->private->state == DEV_STATE_DISCONNECTED) { 498 + spin_lock_irq(cdev->ccwlock); 499 + ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL); 500 + spin_unlock_irq(cdev->ccwlock); 501 + } else if (cdev->online && cdev->drv && cdev->drv->set_offline) 498 502 return ccw_device_set_offline(cdev); 499 503 return 0; 500 504 } 501 505 502 506 static int online_store_recog_and_online(struct ccw_device *cdev) 503 507 { 504 - int ret; 505 - 506 508 /* Do device recognition, if needed. */ 507 509 if (cdev->private->state == DEV_STATE_BOXED) { 508 - ret = ccw_device_recognition(cdev); 509 - if (ret) { 510 - CIO_MSG_EVENT(0, "Couldn't start recognition " 511 - "for device 0.%x.%04x (ret=%d)\n", 512 - cdev->private->dev_id.ssid, 513 - cdev->private->dev_id.devno, ret); 514 - return ret; 515 - } 510 + spin_lock_irq(cdev->ccwlock); 511 + ccw_device_recognition(cdev); 512 + spin_unlock_irq(cdev->ccwlock); 516 513 wait_event(cdev->private->wait_q, 517 514 cdev->private->flags.recog_done); 518 515 if (cdev->private->state != DEV_STATE_OFFLINE) ··· 546 553 int force, ret; 547 554 unsigned long i; 548 555 549 - if ((cdev->private->state != DEV_STATE_OFFLINE && 550 - cdev->private->state != DEV_STATE_ONLINE && 551 - cdev->private->state != DEV_STATE_BOXED && 552 - cdev->private->state != DEV_STATE_DISCONNECTED) || 553 - atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0) 556 + if (!dev_fsm_final_state(cdev) && 557 + cdev->private->state != DEV_STATE_DISCONNECTED) 558 + return -EAGAIN; 559 + if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0) 554 560 return -EAGAIN; 555 561 556 562 if (cdev->drv && !try_module_get(cdev->drv->owner)) { ··· 657 665 cdev->private->dev_id.devno); 658 666 if (ret) 659 667 return ret; 660 - ret = device_add(dev); 661 - if (ret) 662 - return ret; 663 - 664 - set_bit(1, &cdev->private->registered); 665 - return ret; 668 + return device_add(dev); 666 669 } 667 670 668 - struct match_data { 669 - struct ccw_dev_id dev_id; 670 - struct ccw_device * sibling; 671 - }; 672 - 673 - static int 674 - match_devno(struct device * dev, void * data) 671 + static int match_dev_id(struct device *dev, void *data) 675 672 { 676 - struct match_data * d = data; 677 - struct ccw_device * cdev; 673 + struct ccw_device *cdev = to_ccwdev(dev); 674 + struct ccw_dev_id *dev_id = data; 678 675 679 - cdev = to_ccwdev(dev); 680 - if ((cdev->private->state == DEV_STATE_DISCONNECTED) && 681 - !ccw_device_is_orphan(cdev) && 682 - ccw_dev_id_is_equal(&cdev->private->dev_id, &d->dev_id) && 683 - (cdev != d->sibling)) 684 - return 1; 685 - return 0; 686 - } 687 - 688 - static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id, 689 - struct ccw_device *sibling) 690 - { 691 - struct device *dev; 692 - struct match_data data; 693 - 694 - data.dev_id = *dev_id; 695 - data.sibling = sibling; 696 - dev = bus_find_device(&ccw_bus_type, NULL, &data, match_devno); 697 - 698 - return dev ? to_ccwdev(dev) : NULL; 699 - } 700 - 701 - static int match_orphan(struct device *dev, void *data) 702 - { 703 - struct ccw_dev_id *dev_id; 704 - struct ccw_device *cdev; 705 - 706 - dev_id = data; 707 - cdev = to_ccwdev(dev); 708 676 return ccw_dev_id_is_equal(&cdev->private->dev_id, dev_id); 709 677 } 710 678 711 - static struct ccw_device * 712 - get_orphaned_ccwdev_by_dev_id(struct channel_subsystem *css, 713 - struct ccw_dev_id *dev_id) 679 + static struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id) 714 680 { 715 681 struct device *dev; 716 682 717 - dev = device_find_child(&css->pseudo_subchannel->dev, dev_id, 718 - match_orphan); 683 + dev = bus_find_device(&ccw_bus_type, NULL, dev_id, match_dev_id); 719 684 720 685 return dev ? to_ccwdev(dev) : NULL; 721 686 } 722 687 723 - void ccw_device_do_unbind_bind(struct work_struct *work) 688 + static void ccw_device_do_unbind_bind(struct ccw_device *cdev) 724 689 { 725 - struct ccw_device_private *priv; 726 - struct ccw_device *cdev; 727 - struct subchannel *sch; 728 690 int ret; 729 691 730 - priv = container_of(work, struct ccw_device_private, kick_work); 731 - cdev = priv->cdev; 732 - sch = to_subchannel(cdev->dev.parent); 733 - 734 - if (test_bit(1, &cdev->private->registered)) { 692 + if (device_is_registered(&cdev->dev)) { 735 693 device_release_driver(&cdev->dev); 736 694 ret = device_attach(&cdev->dev); 737 695 WARN_ON(ret == -ENODEV); ··· 715 773 return ERR_PTR(-ENOMEM); 716 774 } 717 775 776 + static void ccw_device_todo(struct work_struct *work); 777 + 718 778 static int io_subchannel_initialize_dev(struct subchannel *sch, 719 779 struct ccw_device *cdev) 720 780 { ··· 724 780 atomic_set(&cdev->private->onoff, 0); 725 781 cdev->dev.parent = &sch->dev; 726 782 cdev->dev.release = ccw_device_release; 727 - INIT_WORK(&cdev->private->kick_work, NULL); 783 + INIT_WORK(&cdev->private->todo_work, ccw_device_todo); 728 784 cdev->dev.groups = ccwdev_attr_groups; 729 785 /* Do first half of device_register. */ 730 786 device_initialize(&cdev->dev); ··· 733 789 put_device(&cdev->dev); 734 790 return -ENODEV; 735 791 } 792 + cdev->private->flags.initialized = 1; 736 793 return 0; 737 794 } 738 795 ··· 751 806 return cdev; 752 807 } 753 808 754 - static int io_subchannel_recog(struct ccw_device *, struct subchannel *); 755 - 756 - static void sch_attach_device(struct subchannel *sch, 757 - struct ccw_device *cdev) 758 - { 759 - css_update_ssd_info(sch); 760 - spin_lock_irq(sch->lock); 761 - sch_set_cdev(sch, cdev); 762 - cdev->private->schid = sch->schid; 763 - cdev->ccwlock = sch->lock; 764 - ccw_device_trigger_reprobe(cdev); 765 - spin_unlock_irq(sch->lock); 766 - } 767 - 768 - static void sch_attach_disconnected_device(struct subchannel *sch, 769 - struct ccw_device *cdev) 770 - { 771 - struct subchannel *other_sch; 772 - int ret; 773 - 774 - /* Get reference for new parent. */ 775 - if (!get_device(&sch->dev)) 776 - return; 777 - other_sch = to_subchannel(cdev->dev.parent); 778 - /* Note: device_move() changes cdev->dev.parent */ 779 - ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV); 780 - if (ret) { 781 - CIO_MSG_EVENT(0, "Moving disconnected device 0.%x.%04x failed " 782 - "(ret=%d)!\n", cdev->private->dev_id.ssid, 783 - cdev->private->dev_id.devno, ret); 784 - /* Put reference for new parent. */ 785 - put_device(&sch->dev); 786 - return; 787 - } 788 - sch_set_cdev(other_sch, NULL); 789 - /* No need to keep a subchannel without ccw device around. */ 790 - css_sch_device_unregister(other_sch); 791 - sch_attach_device(sch, cdev); 792 - /* Put reference for old parent. */ 793 - put_device(&other_sch->dev); 794 - } 795 - 796 - static void sch_attach_orphaned_device(struct subchannel *sch, 797 - struct ccw_device *cdev) 798 - { 799 - int ret; 800 - struct subchannel *pseudo_sch; 801 - 802 - /* Get reference for new parent. */ 803 - if (!get_device(&sch->dev)) 804 - return; 805 - pseudo_sch = to_subchannel(cdev->dev.parent); 806 - /* 807 - * Try to move the ccw device to its new subchannel. 808 - * Note: device_move() changes cdev->dev.parent 809 - */ 810 - ret = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV); 811 - if (ret) { 812 - CIO_MSG_EVENT(0, "Moving device 0.%x.%04x from orphanage " 813 - "failed (ret=%d)!\n", 814 - cdev->private->dev_id.ssid, 815 - cdev->private->dev_id.devno, ret); 816 - /* Put reference for new parent. */ 817 - put_device(&sch->dev); 818 - return; 819 - } 820 - sch_attach_device(sch, cdev); 821 - /* Put reference on pseudo subchannel. */ 822 - put_device(&pseudo_sch->dev); 823 - } 809 + static void io_subchannel_recog(struct ccw_device *, struct subchannel *); 824 810 825 811 static void sch_create_and_recog_new_device(struct subchannel *sch) 826 812 { ··· 764 888 css_sch_device_unregister(sch); 765 889 return; 766 890 } 767 - spin_lock_irq(sch->lock); 768 - sch_set_cdev(sch, cdev); 769 - spin_unlock_irq(sch->lock); 770 891 /* Start recognition for the new ccw device. */ 771 - if (io_subchannel_recog(cdev, sch)) { 772 - spin_lock_irq(sch->lock); 773 - sch_set_cdev(sch, NULL); 774 - spin_unlock_irq(sch->lock); 775 - css_sch_device_unregister(sch); 776 - /* Put reference from io_subchannel_create_ccwdev(). */ 777 - put_device(&sch->dev); 778 - /* Give up initial reference. */ 779 - put_device(&cdev->dev); 780 - } 781 - } 782 - 783 - 784 - void ccw_device_move_to_orphanage(struct work_struct *work) 785 - { 786 - struct ccw_device_private *priv; 787 - struct ccw_device *cdev; 788 - struct ccw_device *replacing_cdev; 789 - struct subchannel *sch; 790 - int ret; 791 - struct channel_subsystem *css; 792 - struct ccw_dev_id dev_id; 793 - 794 - priv = container_of(work, struct ccw_device_private, kick_work); 795 - cdev = priv->cdev; 796 - sch = to_subchannel(cdev->dev.parent); 797 - css = to_css(sch->dev.parent); 798 - dev_id.devno = sch->schib.pmcw.dev; 799 - dev_id.ssid = sch->schid.ssid; 800 - 801 - /* Increase refcount for pseudo subchannel. */ 802 - get_device(&css->pseudo_subchannel->dev); 803 - /* 804 - * Move the orphaned ccw device to the orphanage so the replacing 805 - * ccw device can take its place on the subchannel. 806 - * Note: device_move() changes cdev->dev.parent 807 - */ 808 - ret = device_move(&cdev->dev, &css->pseudo_subchannel->dev, 809 - DPM_ORDER_NONE); 810 - if (ret) { 811 - CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to orphanage failed " 812 - "(ret=%d)!\n", cdev->private->dev_id.ssid, 813 - cdev->private->dev_id.devno, ret); 814 - /* Decrease refcount for pseudo subchannel again. */ 815 - put_device(&css->pseudo_subchannel->dev); 816 - return; 817 - } 818 - cdev->ccwlock = css->pseudo_subchannel->lock; 819 - /* 820 - * Search for the replacing ccw device 821 - * - among the disconnected devices 822 - * - in the orphanage 823 - */ 824 - replacing_cdev = get_disc_ccwdev_by_dev_id(&dev_id, cdev); 825 - if (replacing_cdev) { 826 - sch_attach_disconnected_device(sch, replacing_cdev); 827 - /* Release reference from get_disc_ccwdev_by_dev_id() */ 828 - put_device(&replacing_cdev->dev); 829 - /* Release reference of subchannel from old cdev. */ 830 - put_device(&sch->dev); 831 - return; 832 - } 833 - replacing_cdev = get_orphaned_ccwdev_by_dev_id(css, &dev_id); 834 - if (replacing_cdev) { 835 - sch_attach_orphaned_device(sch, replacing_cdev); 836 - /* Release reference from get_orphaned_ccwdev_by_dev_id() */ 837 - put_device(&replacing_cdev->dev); 838 - /* Release reference of subchannel from old cdev. */ 839 - put_device(&sch->dev); 840 - return; 841 - } 842 - sch_create_and_recog_new_device(sch); 843 - /* Release reference of subchannel from old cdev. */ 844 - put_device(&sch->dev); 892 + io_subchannel_recog(cdev, sch); 845 893 } 846 894 847 895 /* 848 896 * Register recognized device. 849 897 */ 850 - static void 851 - io_subchannel_register(struct work_struct *work) 898 + static void io_subchannel_register(struct ccw_device *cdev) 852 899 { 853 - struct ccw_device_private *priv; 854 - struct ccw_device *cdev; 855 900 struct subchannel *sch; 856 901 int ret; 857 902 unsigned long flags; 858 903 859 - priv = container_of(work, struct ccw_device_private, kick_work); 860 - cdev = priv->cdev; 861 904 sch = to_subchannel(cdev->dev.parent); 862 905 /* 863 906 * Check if subchannel is still registered. It may have become ··· 828 1033 cdev->private->flags.recog_done = 1; 829 1034 wake_up(&cdev->private->wait_q); 830 1035 out_err: 831 - /* Release reference for workqueue processing. */ 832 - put_device(&cdev->dev); 833 1036 if (atomic_dec_and_test(&ccw_device_init_count)) 834 1037 wake_up(&ccw_device_init_wq); 835 1038 } 836 1039 837 - static void ccw_device_call_sch_unregister(struct work_struct *work) 1040 + static void ccw_device_call_sch_unregister(struct ccw_device *cdev) 838 1041 { 839 - struct ccw_device_private *priv; 840 - struct ccw_device *cdev; 841 1042 struct subchannel *sch; 842 1043 843 - priv = container_of(work, struct ccw_device_private, kick_work); 844 - cdev = priv->cdev; 845 1044 /* Get subchannel reference for local processing. */ 846 1045 if (!get_device(cdev->dev.parent)) 847 1046 return; 848 1047 sch = to_subchannel(cdev->dev.parent); 849 1048 css_sch_device_unregister(sch); 850 - /* Release cdev reference for workqueue processing.*/ 851 - put_device(&cdev->dev); 852 1049 /* Release subchannel reference for local processing. */ 853 1050 put_device(&sch->dev); 854 - } 855 - 856 - void ccw_device_schedule_sch_unregister(struct ccw_device *cdev) 857 - { 858 - /* Get cdev reference for workqueue processing. */ 859 - if (!get_device(&cdev->dev)) 860 - return; 861 - PREPARE_WORK(&cdev->private->kick_work, 862 - ccw_device_call_sch_unregister); 863 - queue_work(slow_path_wq, &cdev->private->kick_work); 864 1051 } 865 1052 866 1053 /* ··· 860 1083 /* Device did not respond in time. */ 861 1084 case DEV_STATE_NOT_OPER: 862 1085 cdev->private->flags.recog_done = 1; 863 - ccw_device_schedule_sch_unregister(cdev); 1086 + /* Remove device found not operational. */ 1087 + ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); 864 1088 if (atomic_dec_and_test(&ccw_device_init_count)) 865 1089 wake_up(&ccw_device_init_wq); 866 1090 break; ··· 870 1092 * We can't register the device in interrupt context so 871 1093 * we schedule a work item. 872 1094 */ 873 - if (!get_device(&cdev->dev)) 874 - break; 875 - PREPARE_WORK(&cdev->private->kick_work, 876 - io_subchannel_register); 877 - queue_work(slow_path_wq, &cdev->private->kick_work); 1095 + ccw_device_sched_todo(cdev, CDEV_TODO_REGISTER); 878 1096 break; 879 1097 } 880 1098 } 881 1099 882 - static int 883 - io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) 1100 + static void io_subchannel_recog(struct ccw_device *cdev, struct subchannel *sch) 884 1101 { 885 - int rc; 886 1102 struct ccw_device_private *priv; 887 1103 888 - sch_set_cdev(sch, cdev); 889 1104 cdev->ccwlock = sch->lock; 890 1105 891 1106 /* Init private data. */ ··· 896 1125 897 1126 /* Start async. device sensing. */ 898 1127 spin_lock_irq(sch->lock); 899 - rc = ccw_device_recognition(cdev); 1128 + sch_set_cdev(sch, cdev); 1129 + ccw_device_recognition(cdev); 900 1130 spin_unlock_irq(sch->lock); 901 - if (rc) { 902 - if (atomic_dec_and_test(&ccw_device_init_count)) 903 - wake_up(&ccw_device_init_wq); 904 - } 905 - return rc; 906 1131 } 907 1132 908 - static void ccw_device_move_to_sch(struct work_struct *work) 1133 + static int ccw_device_move_to_sch(struct ccw_device *cdev, 1134 + struct subchannel *sch) 909 1135 { 910 - struct ccw_device_private *priv; 911 - int rc; 912 - struct subchannel *sch; 913 - struct ccw_device *cdev; 914 - struct subchannel *former_parent; 1136 + struct subchannel *old_sch; 1137 + int rc, old_enabled = 0; 915 1138 916 - priv = container_of(work, struct ccw_device_private, kick_work); 917 - sch = priv->sch; 918 - cdev = priv->cdev; 919 - former_parent = to_subchannel(cdev->dev.parent); 920 - /* Get reference for new parent. */ 1139 + old_sch = to_subchannel(cdev->dev.parent); 1140 + /* Obtain child reference for new parent. */ 921 1141 if (!get_device(&sch->dev)) 922 - return; 1142 + return -ENODEV; 1143 + 1144 + if (!sch_is_pseudo_sch(old_sch)) { 1145 + spin_lock_irq(old_sch->lock); 1146 + old_enabled = old_sch->schib.pmcw.ena; 1147 + rc = 0; 1148 + if (old_enabled) 1149 + rc = cio_disable_subchannel(old_sch); 1150 + spin_unlock_irq(old_sch->lock); 1151 + if (rc == -EBUSY) { 1152 + /* Release child reference for new parent. */ 1153 + put_device(&sch->dev); 1154 + return rc; 1155 + } 1156 + } 1157 + 923 1158 mutex_lock(&sch->reg_mutex); 924 - /* 925 - * Try to move the ccw device to its new subchannel. 926 - * Note: device_move() changes cdev->dev.parent 927 - */ 928 1159 rc = device_move(&cdev->dev, &sch->dev, DPM_ORDER_PARENT_BEFORE_DEV); 929 1160 mutex_unlock(&sch->reg_mutex); 930 1161 if (rc) { 931 - CIO_MSG_EVENT(0, "Moving device 0.%x.%04x to subchannel " 932 - "0.%x.%04x failed (ret=%d)!\n", 1162 + CIO_MSG_EVENT(0, "device_move(0.%x.%04x,0.%x.%04x)=%d\n", 933 1163 cdev->private->dev_id.ssid, 934 1164 cdev->private->dev_id.devno, sch->schid.ssid, 935 - sch->schid.sch_no, rc); 936 - css_sch_device_unregister(sch); 937 - /* Put reference for new parent again. */ 1165 + sch->schib.pmcw.dev, rc); 1166 + if (old_enabled) { 1167 + /* Try to reenable the old subchannel. */ 1168 + spin_lock_irq(old_sch->lock); 1169 + cio_enable_subchannel(old_sch, (u32)(addr_t)old_sch); 1170 + spin_unlock_irq(old_sch->lock); 1171 + } 1172 + /* Release child reference for new parent. */ 938 1173 put_device(&sch->dev); 939 - goto out; 1174 + return rc; 940 1175 } 941 - if (!sch_is_pseudo_sch(former_parent)) { 942 - spin_lock_irq(former_parent->lock); 943 - sch_set_cdev(former_parent, NULL); 944 - spin_unlock_irq(former_parent->lock); 945 - css_sch_device_unregister(former_parent); 946 - /* Reset intparm to zeroes. */ 947 - former_parent->config.intparm = 0; 948 - cio_commit_config(former_parent); 1176 + /* Clean up old subchannel. */ 1177 + if (!sch_is_pseudo_sch(old_sch)) { 1178 + spin_lock_irq(old_sch->lock); 1179 + sch_set_cdev(old_sch, NULL); 1180 + spin_unlock_irq(old_sch->lock); 1181 + css_schedule_eval(old_sch->schid); 949 1182 } 950 - sch_attach_device(sch, cdev); 951 - out: 952 - /* Put reference for old parent. */ 953 - put_device(&former_parent->dev); 954 - put_device(&cdev->dev); 1183 + /* Release child reference for old parent. */ 1184 + put_device(&old_sch->dev); 1185 + /* Initialize new subchannel. */ 1186 + spin_lock_irq(sch->lock); 1187 + cdev->private->schid = sch->schid; 1188 + cdev->ccwlock = sch->lock; 1189 + if (!sch_is_pseudo_sch(sch)) 1190 + sch_set_cdev(sch, cdev); 1191 + spin_unlock_irq(sch->lock); 1192 + if (!sch_is_pseudo_sch(sch)) 1193 + css_update_ssd_info(sch); 1194 + return 0; 1195 + } 1196 + 1197 + static int ccw_device_move_to_orph(struct ccw_device *cdev) 1198 + { 1199 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 1200 + struct channel_subsystem *css = to_css(sch->dev.parent); 1201 + 1202 + return ccw_device_move_to_sch(cdev, css->pseudo_subchannel); 955 1203 } 956 1204 957 1205 static void io_subchannel_irq(struct subchannel *sch) ··· 989 1199 { 990 1200 memset(&sch->config, 0, sizeof(sch->config)); 991 1201 sch->config.csense = 1; 992 - /* Use subchannel mp mode when there is more than 1 installed CHPID. */ 993 - if ((sch->schib.pmcw.pim & (sch->schib.pmcw.pim - 1)) != 0) 994 - sch->config.mp = 1; 995 1202 } 996 1203 997 1204 static void io_subchannel_init_fields(struct subchannel *sch) ··· 1009 1222 io_subchannel_init_config(sch); 1010 1223 } 1011 1224 1012 - static void io_subchannel_do_unreg(struct work_struct *work) 1013 - { 1014 - struct subchannel *sch; 1015 - 1016 - sch = container_of(work, struct subchannel, work); 1017 - css_sch_device_unregister(sch); 1018 - put_device(&sch->dev); 1019 - } 1020 - 1021 - /* Schedule unregister if we have no cdev. */ 1022 - static void io_subchannel_schedule_removal(struct subchannel *sch) 1023 - { 1024 - get_device(&sch->dev); 1025 - INIT_WORK(&sch->work, io_subchannel_do_unreg); 1026 - queue_work(slow_path_wq, &sch->work); 1027 - } 1028 - 1029 1225 /* 1030 1226 * Note: We always return 0 so that we bind to the device even on error. 1031 1227 * This is needed so that our remove function is called on unregister. ··· 1017 1247 { 1018 1248 struct ccw_device *cdev; 1019 1249 int rc; 1020 - unsigned long flags; 1021 - struct ccw_dev_id dev_id; 1022 1250 1023 1251 if (cio_is_console(sch->schid)) { 1024 1252 rc = sysfs_create_group(&sch->dev.kobj, ··· 1036 1268 cdev = sch_get_cdev(sch); 1037 1269 cdev->dev.groups = ccwdev_attr_groups; 1038 1270 device_initialize(&cdev->dev); 1271 + cdev->private->flags.initialized = 1; 1039 1272 ccw_device_register(cdev); 1040 1273 /* 1041 1274 * Check if the device is already online. If it is ··· 1061 1292 sch->private = kzalloc(sizeof(struct io_subchannel_private), 1062 1293 GFP_KERNEL | GFP_DMA); 1063 1294 if (!sch->private) 1064 - goto out_err; 1065 - /* 1066 - * First check if a fitting device may be found amongst the 1067 - * disconnected devices or in the orphanage. 1068 - */ 1069 - dev_id.devno = sch->schib.pmcw.dev; 1070 - dev_id.ssid = sch->schid.ssid; 1071 - cdev = get_disc_ccwdev_by_dev_id(&dev_id, NULL); 1072 - if (!cdev) 1073 - cdev = get_orphaned_ccwdev_by_dev_id(to_css(sch->dev.parent), 1074 - &dev_id); 1075 - if (cdev) { 1076 - /* 1077 - * Schedule moving the device until when we have a registered 1078 - * subchannel to move to and succeed the probe. We can 1079 - * unregister later again, when the probe is through. 1080 - */ 1081 - cdev->private->sch = sch; 1082 - PREPARE_WORK(&cdev->private->kick_work, 1083 - ccw_device_move_to_sch); 1084 - queue_work(slow_path_wq, &cdev->private->kick_work); 1085 - return 0; 1086 - } 1087 - cdev = io_subchannel_create_ccwdev(sch); 1088 - if (IS_ERR(cdev)) 1089 - goto out_err; 1090 - rc = io_subchannel_recog(cdev, sch); 1091 - if (rc) { 1092 - spin_lock_irqsave(sch->lock, flags); 1093 - io_subchannel_recog_done(cdev); 1094 - spin_unlock_irqrestore(sch->lock, flags); 1095 - } 1295 + goto out_schedule; 1296 + css_schedule_eval(sch->schid); 1096 1297 return 0; 1097 - out_err: 1098 - kfree(sch->private); 1099 - sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group); 1298 + 1100 1299 out_schedule: 1101 - io_subchannel_schedule_removal(sch); 1300 + spin_lock_irq(sch->lock); 1301 + css_sched_sch_todo(sch, SCH_TODO_UNREG); 1302 + spin_unlock_irq(sch->lock); 1102 1303 return 0; 1103 1304 } 1104 1305 ··· 1076 1337 io_subchannel_remove (struct subchannel *sch) 1077 1338 { 1078 1339 struct ccw_device *cdev; 1079 - unsigned long flags; 1080 1340 1081 1341 cdev = sch_get_cdev(sch); 1082 1342 if (!cdev) 1083 - return 0; 1343 + goto out_free; 1344 + io_subchannel_quiesce(sch); 1084 1345 /* Set ccw device to not operational and drop reference. */ 1085 - spin_lock_irqsave(cdev->ccwlock, flags); 1346 + spin_lock_irq(cdev->ccwlock); 1086 1347 sch_set_cdev(sch, NULL); 1087 1348 cdev->private->state = DEV_STATE_NOT_OPER; 1088 - spin_unlock_irqrestore(cdev->ccwlock, flags); 1349 + spin_unlock_irq(cdev->ccwlock); 1089 1350 ccw_device_unregister(cdev); 1351 + out_free: 1090 1352 kfree(sch->private); 1091 1353 sysfs_remove_group(&sch->dev.kobj, &io_subchannel_attr_group); 1092 1354 return 0; 1093 - } 1094 - 1095 - static int io_subchannel_notify(struct subchannel *sch, int event) 1096 - { 1097 - struct ccw_device *cdev; 1098 - 1099 - cdev = sch_get_cdev(sch); 1100 - if (!cdev) 1101 - return 0; 1102 - return ccw_device_notify(cdev, event); 1103 1355 } 1104 1356 1105 1357 static void io_subchannel_verify(struct subchannel *sch) ··· 1102 1372 dev_fsm_event(cdev, DEV_EVENT_VERIFY); 1103 1373 } 1104 1374 1105 - static int check_for_io_on_path(struct subchannel *sch, int mask) 1106 - { 1107 - if (cio_update_schib(sch)) 1108 - return 0; 1109 - if (scsw_actl(&sch->schib.scsw) && sch->schib.pmcw.lpum == mask) 1110 - return 1; 1111 - return 0; 1112 - } 1113 - 1114 - static void terminate_internal_io(struct subchannel *sch, 1115 - struct ccw_device *cdev) 1116 - { 1117 - if (cio_clear(sch)) { 1118 - /* Recheck device in case clear failed. */ 1119 - sch->lpm = 0; 1120 - if (cdev->online) 1121 - dev_fsm_event(cdev, DEV_EVENT_VERIFY); 1122 - else 1123 - css_schedule_eval(sch->schid); 1124 - return; 1125 - } 1126 - cdev->private->state = DEV_STATE_CLEAR_VERIFY; 1127 - /* Request retry of internal operation. */ 1128 - cdev->private->flags.intretry = 1; 1129 - /* Call handler. */ 1130 - if (cdev->handler) 1131 - cdev->handler(cdev, cdev->private->intparm, 1132 - ERR_PTR(-EIO)); 1133 - } 1134 - 1135 1375 static void io_subchannel_terminate_path(struct subchannel *sch, u8 mask) 1136 1376 { 1137 1377 struct ccw_device *cdev; ··· 1109 1409 cdev = sch_get_cdev(sch); 1110 1410 if (!cdev) 1111 1411 return; 1112 - if (check_for_io_on_path(sch, mask)) { 1113 - if (cdev->private->state == DEV_STATE_ONLINE) 1114 - ccw_device_kill_io(cdev); 1115 - else { 1116 - terminate_internal_io(sch, cdev); 1117 - /* Re-start path verification. */ 1118 - dev_fsm_event(cdev, DEV_EVENT_VERIFY); 1119 - } 1120 - } else 1121 - /* trigger path verification. */ 1122 - dev_fsm_event(cdev, DEV_EVENT_VERIFY); 1412 + if (cio_update_schib(sch)) 1413 + goto err; 1414 + /* Check for I/O on path. */ 1415 + if (scsw_actl(&sch->schib.scsw) == 0 || sch->schib.pmcw.lpum != mask) 1416 + goto out; 1417 + if (cdev->private->state == DEV_STATE_ONLINE) { 1418 + ccw_device_kill_io(cdev); 1419 + goto out; 1420 + } 1421 + if (cio_clear(sch)) 1422 + goto err; 1423 + out: 1424 + /* Trigger path verification. */ 1425 + dev_fsm_event(cdev, DEV_EVENT_VERIFY); 1426 + return; 1123 1427 1428 + err: 1429 + dev_fsm_event(cdev, DEV_EVENT_NOTOPER); 1124 1430 } 1125 1431 1126 1432 static int io_subchannel_chp_event(struct subchannel *sch, ··· 1163 1457 return 0; 1164 1458 } 1165 1459 1166 - static void 1167 - io_subchannel_shutdown(struct subchannel *sch) 1460 + static void io_subchannel_quiesce(struct subchannel *sch) 1168 1461 { 1169 1462 struct ccw_device *cdev; 1170 1463 int ret; 1171 1464 1465 + spin_lock_irq(sch->lock); 1172 1466 cdev = sch_get_cdev(sch); 1173 - 1174 1467 if (cio_is_console(sch->schid)) 1175 - return; 1468 + goto out_unlock; 1176 1469 if (!sch->schib.pmcw.ena) 1177 - /* Nothing to do. */ 1178 - return; 1470 + goto out_unlock; 1179 1471 ret = cio_disable_subchannel(sch); 1180 1472 if (ret != -EBUSY) 1181 - /* Subchannel is disabled, we're done. */ 1182 - return; 1183 - cdev->private->state = DEV_STATE_QUIESCE; 1473 + goto out_unlock; 1184 1474 if (cdev->handler) 1185 - cdev->handler(cdev, cdev->private->intparm, 1186 - ERR_PTR(-EIO)); 1187 - ret = ccw_device_cancel_halt_clear(cdev); 1188 - if (ret == -EBUSY) { 1189 - ccw_device_set_timeout(cdev, HZ/10); 1190 - wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev)); 1475 + cdev->handler(cdev, cdev->private->intparm, ERR_PTR(-EIO)); 1476 + while (ret == -EBUSY) { 1477 + cdev->private->state = DEV_STATE_QUIESCE; 1478 + ret = ccw_device_cancel_halt_clear(cdev); 1479 + if (ret == -EBUSY) { 1480 + ccw_device_set_timeout(cdev, HZ/10); 1481 + spin_unlock_irq(sch->lock); 1482 + wait_event(cdev->private->wait_q, 1483 + cdev->private->state != DEV_STATE_QUIESCE); 1484 + spin_lock_irq(sch->lock); 1485 + } 1486 + ret = cio_disable_subchannel(sch); 1191 1487 } 1192 - cio_disable_subchannel(sch); 1488 + out_unlock: 1489 + spin_unlock_irq(sch->lock); 1193 1490 } 1194 1491 1195 - static int io_subchannel_get_status(struct subchannel *sch) 1492 + static void io_subchannel_shutdown(struct subchannel *sch) 1196 1493 { 1197 - struct schib schib; 1198 - 1199 - if (stsch(sch->schid, &schib) || !schib.pmcw.dnv) 1200 - return CIO_GONE; 1201 - if (sch->schib.pmcw.dnv && (schib.pmcw.dev != sch->schib.pmcw.dev)) 1202 - return CIO_REVALIDATE; 1203 - if (!sch->lpm) 1204 - return CIO_NO_PATH; 1205 - return CIO_OPER; 1494 + io_subchannel_quiesce(sch); 1206 1495 } 1207 1496 1208 1497 static int device_is_disconnected(struct ccw_device *cdev) ··· 1276 1575 static int purge_fn(struct device *dev, void *data) 1277 1576 { 1278 1577 struct ccw_device *cdev = to_ccwdev(dev); 1279 - struct ccw_device_private *priv = cdev->private; 1280 - int unreg; 1578 + struct ccw_dev_id *id = &cdev->private->dev_id; 1281 1579 1282 1580 spin_lock_irq(cdev->ccwlock); 1283 - unreg = is_blacklisted(priv->dev_id.ssid, priv->dev_id.devno) && 1284 - (priv->state == DEV_STATE_OFFLINE); 1581 + if (is_blacklisted(id->ssid, id->devno) && 1582 + (cdev->private->state == DEV_STATE_OFFLINE)) { 1583 + CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", id->ssid, 1584 + id->devno); 1585 + ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); 1586 + } 1285 1587 spin_unlock_irq(cdev->ccwlock); 1286 - if (!unreg) 1287 - goto out; 1288 - CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid, 1289 - priv->dev_id.devno); 1290 - ccw_device_schedule_sch_unregister(cdev); 1291 - 1292 - out: 1293 1588 /* Abort loop in case of pending signal. */ 1294 1589 if (signal_pending(current)) 1295 1590 return -EINTR; ··· 1327 1630 cdev->private->state = DEV_STATE_NOT_OPER; 1328 1631 } 1329 1632 1330 - static int io_subchannel_sch_event(struct subchannel *sch, int slow) 1633 + enum io_sch_action { 1634 + IO_SCH_UNREG, 1635 + IO_SCH_ORPH_UNREG, 1636 + IO_SCH_ATTACH, 1637 + IO_SCH_UNREG_ATTACH, 1638 + IO_SCH_ORPH_ATTACH, 1639 + IO_SCH_REPROBE, 1640 + IO_SCH_VERIFY, 1641 + IO_SCH_DISC, 1642 + IO_SCH_NOP, 1643 + }; 1644 + 1645 + static enum io_sch_action sch_get_action(struct subchannel *sch) 1331 1646 { 1332 - int event, ret, disc; 1333 - unsigned long flags; 1334 - enum { NONE, UNREGISTER, UNREGISTER_PROBE, REPROBE, DISC } action; 1335 1647 struct ccw_device *cdev; 1336 1648 1337 - spin_lock_irqsave(sch->lock, flags); 1338 1649 cdev = sch_get_cdev(sch); 1339 - disc = device_is_disconnected(cdev); 1340 - if (disc && slow) { 1341 - /* Disconnected devices are evaluated directly only.*/ 1342 - spin_unlock_irqrestore(sch->lock, flags); 1343 - return 0; 1650 + if (cio_update_schib(sch)) { 1651 + /* Not operational. */ 1652 + if (!cdev) 1653 + return IO_SCH_UNREG; 1654 + if (!ccw_device_notify(cdev, CIO_GONE)) 1655 + return IO_SCH_UNREG; 1656 + return IO_SCH_ORPH_UNREG; 1344 1657 } 1345 - /* No interrupt after machine check - kill pending timers. */ 1346 - if (cdev) 1347 - ccw_device_set_timeout(cdev, 0); 1348 - if (!disc && !slow) { 1349 - /* Non-disconnected devices are evaluated on the slow path. */ 1350 - spin_unlock_irqrestore(sch->lock, flags); 1351 - return -EAGAIN; 1658 + /* Operational. */ 1659 + if (!cdev) 1660 + return IO_SCH_ATTACH; 1661 + if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { 1662 + if (!ccw_device_notify(cdev, CIO_GONE)) 1663 + return IO_SCH_UNREG_ATTACH; 1664 + return IO_SCH_ORPH_ATTACH; 1352 1665 } 1353 - event = io_subchannel_get_status(sch); 1354 - CIO_MSG_EVENT(4, "Evaluating schid 0.%x.%04x, event %d, %s, %s path.\n", 1355 - sch->schid.ssid, sch->schid.sch_no, event, 1356 - disc ? "disconnected" : "normal", 1357 - slow ? "slow" : "fast"); 1358 - /* Analyze subchannel status. */ 1359 - action = NONE; 1360 - switch (event) { 1361 - case CIO_NO_PATH: 1362 - if (disc) { 1363 - /* Check if paths have become available. */ 1364 - action = REPROBE; 1365 - break; 1366 - } 1367 - /* fall through */ 1368 - case CIO_GONE: 1369 - /* Ask driver what to do with device. */ 1370 - if (io_subchannel_notify(sch, event)) 1371 - action = DISC; 1372 - else 1373 - action = UNREGISTER; 1374 - break; 1375 - case CIO_REVALIDATE: 1376 - /* Device will be removed, so no notify necessary. */ 1377 - if (disc) 1378 - /* Reprobe because immediate unregister might block. */ 1379 - action = REPROBE; 1380 - else 1381 - action = UNREGISTER_PROBE; 1382 - break; 1383 - case CIO_OPER: 1384 - if (disc) 1385 - /* Get device operational again. */ 1386 - action = REPROBE; 1387 - break; 1666 + if ((sch->schib.pmcw.pam & sch->opm) == 0) { 1667 + if (!ccw_device_notify(cdev, CIO_NO_PATH)) 1668 + return IO_SCH_UNREG; 1669 + return IO_SCH_DISC; 1388 1670 } 1389 - /* Perform action. */ 1390 - ret = 0; 1671 + if (device_is_disconnected(cdev)) 1672 + return IO_SCH_REPROBE; 1673 + if (cdev->online) 1674 + return IO_SCH_VERIFY; 1675 + return IO_SCH_NOP; 1676 + } 1677 + 1678 + /** 1679 + * io_subchannel_sch_event - process subchannel event 1680 + * @sch: subchannel 1681 + * @process: non-zero if function is called in process context 1682 + * 1683 + * An unspecified event occurred for this subchannel. Adjust data according 1684 + * to the current operational state of the subchannel and device. Return 1685 + * zero when the event has been handled sufficiently or -EAGAIN when this 1686 + * function should be called again in process context. 1687 + */ 1688 + static int io_subchannel_sch_event(struct subchannel *sch, int process) 1689 + { 1690 + unsigned long flags; 1691 + struct ccw_device *cdev; 1692 + struct ccw_dev_id dev_id; 1693 + enum io_sch_action action; 1694 + int rc = -EAGAIN; 1695 + 1696 + spin_lock_irqsave(sch->lock, flags); 1697 + if (!device_is_registered(&sch->dev)) 1698 + goto out_unlock; 1699 + if (work_pending(&sch->todo_work)) 1700 + goto out_unlock; 1701 + cdev = sch_get_cdev(sch); 1702 + if (cdev && work_pending(&cdev->private->todo_work)) 1703 + goto out_unlock; 1704 + action = sch_get_action(sch); 1705 + CIO_MSG_EVENT(2, "event: sch 0.%x.%04x, process=%d, action=%d\n", 1706 + sch->schid.ssid, sch->schid.sch_no, process, 1707 + action); 1708 + /* Perform immediate actions while holding the lock. */ 1391 1709 switch (action) { 1392 - case UNREGISTER: 1393 - case UNREGISTER_PROBE: 1394 - ccw_device_set_notoper(cdev); 1395 - /* Unregister device (will use subchannel lock). */ 1396 - spin_unlock_irqrestore(sch->lock, flags); 1397 - css_sch_device_unregister(sch); 1398 - spin_lock_irqsave(sch->lock, flags); 1399 - break; 1400 - case REPROBE: 1710 + case IO_SCH_REPROBE: 1711 + /* Trigger device recognition. */ 1401 1712 ccw_device_trigger_reprobe(cdev); 1402 - break; 1403 - case DISC: 1713 + rc = 0; 1714 + goto out_unlock; 1715 + case IO_SCH_VERIFY: 1716 + /* Trigger path verification. */ 1717 + io_subchannel_verify(sch); 1718 + rc = 0; 1719 + goto out_unlock; 1720 + case IO_SCH_DISC: 1721 + ccw_device_set_disconnected(cdev); 1722 + rc = 0; 1723 + goto out_unlock; 1724 + case IO_SCH_ORPH_UNREG: 1725 + case IO_SCH_ORPH_ATTACH: 1404 1726 ccw_device_set_disconnected(cdev); 1405 1727 break; 1728 + case IO_SCH_UNREG_ATTACH: 1729 + case IO_SCH_UNREG: 1730 + if (cdev) 1731 + ccw_device_set_notoper(cdev); 1732 + break; 1733 + case IO_SCH_NOP: 1734 + rc = 0; 1735 + goto out_unlock; 1406 1736 default: 1407 1737 break; 1408 1738 } 1409 1739 spin_unlock_irqrestore(sch->lock, flags); 1410 - /* Probe if necessary. */ 1411 - if (action == UNREGISTER_PROBE) 1412 - ret = css_probe_device(sch->schid); 1740 + /* All other actions require process context. */ 1741 + if (!process) 1742 + goto out; 1743 + /* Handle attached ccw device. */ 1744 + switch (action) { 1745 + case IO_SCH_ORPH_UNREG: 1746 + case IO_SCH_ORPH_ATTACH: 1747 + /* Move ccw device to orphanage. */ 1748 + rc = ccw_device_move_to_orph(cdev); 1749 + if (rc) 1750 + goto out; 1751 + break; 1752 + case IO_SCH_UNREG_ATTACH: 1753 + /* Unregister ccw device. */ 1754 + ccw_device_unregister(cdev); 1755 + break; 1756 + default: 1757 + break; 1758 + } 1759 + /* Handle subchannel. */ 1760 + switch (action) { 1761 + case IO_SCH_ORPH_UNREG: 1762 + case IO_SCH_UNREG: 1763 + css_sch_device_unregister(sch); 1764 + break; 1765 + case IO_SCH_ORPH_ATTACH: 1766 + case IO_SCH_UNREG_ATTACH: 1767 + case IO_SCH_ATTACH: 1768 + dev_id.ssid = sch->schid.ssid; 1769 + dev_id.devno = sch->schib.pmcw.dev; 1770 + cdev = get_ccwdev_by_dev_id(&dev_id); 1771 + if (!cdev) { 1772 + sch_create_and_recog_new_device(sch); 1773 + break; 1774 + } 1775 + rc = ccw_device_move_to_sch(cdev, sch); 1776 + if (rc) { 1777 + /* Release reference from get_ccwdev_by_dev_id() */ 1778 + put_device(&cdev->dev); 1779 + goto out; 1780 + } 1781 + spin_lock_irqsave(sch->lock, flags); 1782 + ccw_device_trigger_reprobe(cdev); 1783 + spin_unlock_irqrestore(sch->lock, flags); 1784 + /* Release reference from get_ccwdev_by_dev_id() */ 1785 + put_device(&cdev->dev); 1786 + break; 1787 + default: 1788 + break; 1789 + } 1790 + return 0; 1413 1791 1414 - return ret; 1792 + out_unlock: 1793 + spin_unlock_irqrestore(sch->lock, flags); 1794 + out: 1795 + return rc; 1415 1796 } 1416 1797 1417 1798 #ifdef CONFIG_CCW_CONSOLE ··· 1519 1744 sch->driver = &io_subchannel_driver; 1520 1745 /* Initialize the ccw_device structure. */ 1521 1746 cdev->dev.parent= &sch->dev; 1522 - rc = io_subchannel_recog(cdev, sch); 1523 - if (rc) 1524 - return rc; 1525 - 1747 + io_subchannel_recog(cdev, sch); 1526 1748 /* Now wait for the async. recognition to come to an end. */ 1527 1749 spin_lock_irq(cdev->ccwlock); 1528 1750 while (!dev_fsm_final_state(cdev)) ··· 1535 1763 rc = 0; 1536 1764 out_unlock: 1537 1765 spin_unlock_irq(cdev->ccwlock); 1538 - return 0; 1766 + return rc; 1539 1767 } 1540 1768 1541 1769 struct ccw_device * ··· 1691 1919 { 1692 1920 struct ccw_device *cdev = to_ccwdev(dev); 1693 1921 1694 - if (work_pending(&cdev->private->kick_work)) 1922 + if (work_pending(&cdev->private->todo_work)) 1695 1923 return -EAGAIN; 1696 1924 /* Fail while device is being set online/offline. */ 1697 1925 if (atomic_read(&cdev->private->onoff)) ··· 1777 2005 static void __ccw_device_pm_restore(struct ccw_device *cdev) 1778 2006 { 1779 2007 struct subchannel *sch = to_subchannel(cdev->dev.parent); 1780 - int ret; 1781 2008 1782 2009 if (cio_is_console(sch->schid)) 1783 2010 goto out; ··· 1786 2015 */ 1787 2016 spin_lock_irq(sch->lock); 1788 2017 cdev->private->flags.resuming = 1; 1789 - ret = ccw_device_recognition(cdev); 2018 + ccw_device_recognition(cdev); 1790 2019 spin_unlock_irq(sch->lock); 1791 - if (ret) { 1792 - CIO_MSG_EVENT(0, "Couldn't start recognition for device " 1793 - "0.%x.%04x (ret=%d)\n", 1794 - cdev->private->dev_id.ssid, 1795 - cdev->private->dev_id.devno, ret); 1796 - spin_lock_irq(sch->lock); 1797 - cdev->private->state = DEV_STATE_DISCONNECTED; 1798 - spin_unlock_irq(sch->lock); 1799 - /* notify driver after the resume cb */ 1800 - goto out; 1801 - } 1802 2020 wait_event(cdev->private->wait_q, dev_fsm_final_state(cdev) || 1803 2021 cdev->private->state == DEV_STATE_DISCONNECTED); 1804 - 1805 2022 out: 1806 2023 cdev->private->flags.resuming = 0; 1807 2024 } ··· 1799 2040 cdev->private->state = DEV_STATE_BOXED; 1800 2041 if (ccw_device_notify(cdev, CIO_BOXED)) 1801 2042 return 0; 1802 - ccw_device_schedule_sch_unregister(cdev); 2043 + ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); 1803 2044 return -ENODEV; 1804 2045 } 1805 2046 ··· 1808 2049 cdev->private->state = DEV_STATE_DISCONNECTED; 1809 2050 if (ccw_device_notify(cdev, CIO_GONE)) 1810 2051 return 0; 1811 - ccw_device_schedule_sch_unregister(cdev); 2052 + ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); 1812 2053 return -ENODEV; 1813 2054 } 1814 2055 ··· 1853 2094 /* check if the device type has changed */ 1854 2095 if (!ccw_device_test_sense_data(cdev)) { 1855 2096 ccw_device_update_sense_data(cdev); 1856 - PREPARE_WORK(&cdev->private->kick_work, 1857 - ccw_device_do_unbind_bind); 1858 - queue_work(ccw_device_work, &cdev->private->kick_work); 2097 + ccw_device_sched_todo(cdev, CDEV_TODO_REBIND); 1859 2098 ret = -ENODEV; 1860 2099 goto out_unlock; 1861 2100 } ··· 1897 2140 goto out_restore; 1898 2141 1899 2142 out_unreg_unlock: 1900 - ccw_device_schedule_sch_unregister(cdev); 2143 + ccw_device_sched_todo(cdev, CDEV_TODO_UNREG_EVAL); 1901 2144 ret = -ENODEV; 1902 2145 out_unlock: 1903 2146 spin_unlock_irq(sch->lock); ··· 1960 2203 1961 2204 sch = to_subchannel(cdev->dev.parent); 1962 2205 return sch->schid; 2206 + } 2207 + 2208 + static void ccw_device_todo(struct work_struct *work) 2209 + { 2210 + struct ccw_device_private *priv; 2211 + struct ccw_device *cdev; 2212 + struct subchannel *sch; 2213 + enum cdev_todo todo; 2214 + 2215 + priv = container_of(work, struct ccw_device_private, todo_work); 2216 + cdev = priv->cdev; 2217 + sch = to_subchannel(cdev->dev.parent); 2218 + /* Find out todo. */ 2219 + spin_lock_irq(cdev->ccwlock); 2220 + todo = priv->todo; 2221 + priv->todo = CDEV_TODO_NOTHING; 2222 + CIO_MSG_EVENT(4, "cdev_todo: cdev=0.%x.%04x todo=%d\n", 2223 + priv->dev_id.ssid, priv->dev_id.devno, todo); 2224 + spin_unlock_irq(cdev->ccwlock); 2225 + /* Perform todo. */ 2226 + switch (todo) { 2227 + case CDEV_TODO_ENABLE_CMF: 2228 + cmf_reenable(cdev); 2229 + break; 2230 + case CDEV_TODO_REBIND: 2231 + ccw_device_do_unbind_bind(cdev); 2232 + break; 2233 + case CDEV_TODO_REGISTER: 2234 + io_subchannel_register(cdev); 2235 + break; 2236 + case CDEV_TODO_UNREG_EVAL: 2237 + if (!sch_is_pseudo_sch(sch)) 2238 + css_schedule_eval(sch->schid); 2239 + /* fall-through */ 2240 + case CDEV_TODO_UNREG: 2241 + if (sch_is_pseudo_sch(sch)) 2242 + ccw_device_unregister(cdev); 2243 + else 2244 + ccw_device_call_sch_unregister(cdev); 2245 + break; 2246 + default: 2247 + break; 2248 + } 2249 + /* Release workqueue ref. */ 2250 + put_device(&cdev->dev); 2251 + } 2252 + 2253 + /** 2254 + * ccw_device_sched_todo - schedule ccw device operation 2255 + * @cdev: ccw device 2256 + * @todo: todo 2257 + * 2258 + * Schedule the operation identified by @todo to be performed on the slow path 2259 + * workqueue. Do nothing if another operation with higher priority is already 2260 + * scheduled. Needs to be called with ccwdev lock held. 2261 + */ 2262 + void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo) 2263 + { 2264 + CIO_MSG_EVENT(4, "cdev_todo: sched cdev=0.%x.%04x todo=%d\n", 2265 + cdev->private->dev_id.ssid, cdev->private->dev_id.devno, 2266 + todo); 2267 + if (cdev->private->todo >= todo) 2268 + return; 2269 + cdev->private->todo = todo; 2270 + /* Get workqueue ref. */ 2271 + if (!get_device(&cdev->dev)) 2272 + return; 2273 + if (!queue_work(slow_path_wq, &cdev->private->todo_work)) { 2274 + /* Already queued, release workqueue ref. */ 2275 + put_device(&cdev->dev); 2276 + } 1963 2277 } 1964 2278 1965 2279 MODULE_LICENSE("GPL");
+14 -11
drivers/s390/cio/device.h
··· 21 21 DEV_STATE_DISBAND_PGID, 22 22 DEV_STATE_BOXED, 23 23 /* states to wait for i/o completion before doing something */ 24 - DEV_STATE_CLEAR_VERIFY, 25 24 DEV_STATE_TIMEOUT_KILL, 26 25 DEV_STATE_QUIESCE, 27 26 /* special states for devices gone not operational */ ··· 28 29 DEV_STATE_DISCONNECTED_SENSE_ID, 29 30 DEV_STATE_CMFCHANGE, 30 31 DEV_STATE_CMFUPDATE, 32 + DEV_STATE_STEAL_LOCK, 31 33 /* last element! */ 32 34 NR_DEV_STATES 33 35 }; ··· 81 81 82 82 int ccw_device_cancel_halt_clear(struct ccw_device *); 83 83 84 - void ccw_device_do_unbind_bind(struct work_struct *); 85 - void ccw_device_move_to_orphanage(struct work_struct *); 86 84 int ccw_device_is_orphan(struct ccw_device *); 87 85 88 - int ccw_device_recognition(struct ccw_device *); 86 + void ccw_device_recognition(struct ccw_device *); 89 87 int ccw_device_online(struct ccw_device *); 90 88 int ccw_device_offline(struct ccw_device *); 91 89 void ccw_device_update_sense_data(struct ccw_device *); 92 90 int ccw_device_test_sense_data(struct ccw_device *); 93 91 void ccw_device_schedule_sch_unregister(struct ccw_device *); 94 92 int ccw_purge_blacklisted(void); 93 + void ccw_device_sched_todo(struct ccw_device *cdev, enum cdev_todo todo); 95 94 96 95 /* Function prototypes for device status and basic sense stuff. */ 97 96 void ccw_device_accumulate_irb(struct ccw_device *, struct irb *); ··· 98 99 int ccw_device_accumulate_and_sense(struct ccw_device *, struct irb *); 99 100 int ccw_device_do_sense(struct ccw_device *, struct irb *); 100 101 102 + /* Function prototype for internal request handling. */ 103 + int lpm_adjust(int lpm, int mask); 104 + void ccw_request_start(struct ccw_device *); 105 + int ccw_request_cancel(struct ccw_device *cdev); 106 + void ccw_request_handler(struct ccw_device *cdev); 107 + void ccw_request_timeout(struct ccw_device *cdev); 108 + void ccw_request_notoper(struct ccw_device *cdev); 109 + 101 110 /* Function prototypes for sense id stuff. */ 102 111 void ccw_device_sense_id_start(struct ccw_device *); 103 - void ccw_device_sense_id_irq(struct ccw_device *, enum dev_event); 104 112 void ccw_device_sense_id_done(struct ccw_device *, int); 105 113 106 114 /* Function prototypes for path grouping stuff. */ 107 - void ccw_device_sense_pgid_start(struct ccw_device *); 108 - void ccw_device_sense_pgid_irq(struct ccw_device *, enum dev_event); 109 - void ccw_device_sense_pgid_done(struct ccw_device *, int); 110 - 111 115 void ccw_device_verify_start(struct ccw_device *); 112 - void ccw_device_verify_irq(struct ccw_device *, enum dev_event); 113 116 void ccw_device_verify_done(struct ccw_device *, int); 114 117 115 118 void ccw_device_disband_start(struct ccw_device *); 116 - void ccw_device_disband_irq(struct ccw_device *, enum dev_event); 117 119 void ccw_device_disband_done(struct ccw_device *, int); 120 + 121 + void ccw_device_stlck_start(struct ccw_device *, void *, void *, void *); 122 + void ccw_device_stlck_done(struct ccw_device *, void *, int); 118 123 119 124 int ccw_device_call_handler(struct ccw_device *); 120 125
+94 -317
drivers/s390/cio/device_fsm.c
··· 229 229 230 230 sch = to_subchannel(cdev->dev.parent); 231 231 232 - ccw_device_set_timeout(cdev, 0); 233 - cio_disable_subchannel(sch); 232 + if (cio_disable_subchannel(sch)) 233 + state = DEV_STATE_NOT_OPER; 234 234 /* 235 235 * Now that we tried recognition, we have performed device selection 236 236 * through ssch() and the path information is up to date. ··· 263 263 } 264 264 switch (state) { 265 265 case DEV_STATE_NOT_OPER: 266 - CIO_MSG_EVENT(2, "SenseID : unknown device %04x on " 267 - "subchannel 0.%x.%04x\n", 268 - cdev->private->dev_id.devno, 269 - sch->schid.ssid, sch->schid.sch_no); 270 266 break; 271 267 case DEV_STATE_OFFLINE: 272 268 if (!cdev->online) { 273 269 ccw_device_update_sense_data(cdev); 274 - /* Issue device info message. */ 275 - CIO_MSG_EVENT(4, "SenseID : device 0.%x.%04x reports: " 276 - "CU Type/Mod = %04X/%02X, Dev Type/Mod " 277 - "= %04X/%02X\n", 278 - cdev->private->dev_id.ssid, 279 - cdev->private->dev_id.devno, 280 - cdev->id.cu_type, cdev->id.cu_model, 281 - cdev->id.dev_type, cdev->id.dev_model); 282 270 break; 283 271 } 284 272 cdev->private->state = DEV_STATE_OFFLINE; ··· 277 289 wake_up(&cdev->private->wait_q); 278 290 } else { 279 291 ccw_device_update_sense_data(cdev); 280 - PREPARE_WORK(&cdev->private->kick_work, 281 - ccw_device_do_unbind_bind); 282 - queue_work(ccw_device_work, &cdev->private->kick_work); 292 + ccw_device_sched_todo(cdev, CDEV_TODO_REBIND); 283 293 } 284 294 return; 285 295 case DEV_STATE_BOXED: 286 - CIO_MSG_EVENT(0, "SenseID : boxed device %04x on " 287 - " subchannel 0.%x.%04x\n", 288 - cdev->private->dev_id.devno, 289 - sch->schid.ssid, sch->schid.sch_no); 290 296 if (cdev->id.cu_type != 0) { /* device was recognized before */ 291 297 cdev->private->flags.recog_done = 1; 292 298 cdev->private->state = DEV_STATE_BOXED; ··· 325 343 return cdev->drv->notify ? cdev->drv->notify(cdev, event) : 0; 326 344 } 327 345 328 - static void cmf_reenable_delayed(struct work_struct *work) 329 - { 330 - struct ccw_device_private *priv; 331 - struct ccw_device *cdev; 332 - 333 - priv = container_of(work, struct ccw_device_private, kick_work); 334 - cdev = priv->cdev; 335 - cmf_reenable(cdev); 336 - } 337 - 338 346 static void ccw_device_oper_notify(struct ccw_device *cdev) 339 347 { 340 348 if (ccw_device_notify(cdev, CIO_OPER)) { 341 349 /* Reenable channel measurements, if needed. */ 342 - PREPARE_WORK(&cdev->private->kick_work, cmf_reenable_delayed); 343 - queue_work(ccw_device_work, &cdev->private->kick_work); 350 + ccw_device_sched_todo(cdev, CDEV_TODO_ENABLE_CMF); 344 351 return; 345 352 } 346 353 /* Driver doesn't want device back. */ 347 354 ccw_device_set_notoper(cdev); 348 - PREPARE_WORK(&cdev->private->kick_work, ccw_device_do_unbind_bind); 349 - queue_work(ccw_device_work, &cdev->private->kick_work); 355 + ccw_device_sched_todo(cdev, CDEV_TODO_REBIND); 350 356 } 351 357 352 358 /* ··· 362 392 CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n", 363 393 cdev->private->dev_id.devno, sch->schid.sch_no); 364 394 if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED)) 365 - ccw_device_schedule_sch_unregister(cdev); 395 + ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); 366 396 cdev->private->flags.donotify = 0; 367 397 break; 368 398 case DEV_STATE_NOT_OPER: 369 399 CIO_MSG_EVENT(0, "Device %04x gone on subchannel %04x\n", 370 400 cdev->private->dev_id.devno, sch->schid.sch_no); 371 401 if (!ccw_device_notify(cdev, CIO_GONE)) 372 - ccw_device_schedule_sch_unregister(cdev); 402 + ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); 373 403 else 374 404 ccw_device_set_disconnected(cdev); 375 405 cdev->private->flags.donotify = 0; ··· 379 409 "%04x\n", cdev->private->dev_id.devno, 380 410 sch->schid.sch_no); 381 411 if (!ccw_device_notify(cdev, CIO_NO_PATH)) 382 - ccw_device_schedule_sch_unregister(cdev); 412 + ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); 383 413 else 384 414 ccw_device_set_disconnected(cdev); 385 415 cdev->private->flags.donotify = 0; ··· 395 425 wake_up(&cdev->private->wait_q); 396 426 } 397 427 398 - static int cmp_pgid(struct pgid *p1, struct pgid *p2) 399 - { 400 - char *c1; 401 - char *c2; 402 - 403 - c1 = (char *)p1; 404 - c2 = (char *)p2; 405 - 406 - return memcmp(c1 + 1, c2 + 1, sizeof(struct pgid) - 1); 407 - } 408 - 409 - static void __ccw_device_get_common_pgid(struct ccw_device *cdev) 410 - { 411 - int i; 412 - int last; 413 - 414 - last = 0; 415 - for (i = 0; i < 8; i++) { 416 - if (cdev->private->pgid[i].inf.ps.state1 == SNID_STATE1_RESET) 417 - /* No PGID yet */ 418 - continue; 419 - if (cdev->private->pgid[last].inf.ps.state1 == 420 - SNID_STATE1_RESET) { 421 - /* First non-zero PGID */ 422 - last = i; 423 - continue; 424 - } 425 - if (cmp_pgid(&cdev->private->pgid[i], 426 - &cdev->private->pgid[last]) == 0) 427 - /* Non-conflicting PGIDs */ 428 - continue; 429 - 430 - /* PGID mismatch, can't pathgroup. */ 431 - CIO_MSG_EVENT(0, "SNID - pgid mismatch for device " 432 - "0.%x.%04x, can't pathgroup\n", 433 - cdev->private->dev_id.ssid, 434 - cdev->private->dev_id.devno); 435 - cdev->private->options.pgroup = 0; 436 - return; 437 - } 438 - if (cdev->private->pgid[last].inf.ps.state1 == 439 - SNID_STATE1_RESET) 440 - /* No previous pgid found */ 441 - memcpy(&cdev->private->pgid[0], 442 - &channel_subsystems[0]->global_pgid, 443 - sizeof(struct pgid)); 444 - else 445 - /* Use existing pgid */ 446 - memcpy(&cdev->private->pgid[0], &cdev->private->pgid[last], 447 - sizeof(struct pgid)); 448 - } 449 - 450 - /* 451 - * Function called from device_pgid.c after sense path ground has completed. 452 - */ 453 - void 454 - ccw_device_sense_pgid_done(struct ccw_device *cdev, int err) 455 - { 456 - struct subchannel *sch; 457 - 458 - sch = to_subchannel(cdev->dev.parent); 459 - switch (err) { 460 - case -EOPNOTSUPP: /* path grouping not supported, use nop instead. */ 461 - cdev->private->options.pgroup = 0; 462 - break; 463 - case 0: /* success */ 464 - case -EACCES: /* partial success, some paths not operational */ 465 - /* Check if all pgids are equal or 0. */ 466 - __ccw_device_get_common_pgid(cdev); 467 - break; 468 - case -ETIME: /* Sense path group id stopped by timeout. */ 469 - case -EUSERS: /* device is reserved for someone else. */ 470 - ccw_device_done(cdev, DEV_STATE_BOXED); 471 - return; 472 - default: 473 - ccw_device_done(cdev, DEV_STATE_NOT_OPER); 474 - return; 475 - } 476 - /* Start Path Group verification. */ 477 - cdev->private->state = DEV_STATE_VERIFY; 478 - cdev->private->flags.doverify = 0; 479 - ccw_device_verify_start(cdev); 480 - } 481 - 482 428 /* 483 429 * Start device recognition. 484 430 */ 485 - int 486 - ccw_device_recognition(struct ccw_device *cdev) 431 + void ccw_device_recognition(struct ccw_device *cdev) 487 432 { 488 - struct subchannel *sch; 489 - int ret; 490 - 491 - sch = to_subchannel(cdev->dev.parent); 492 - ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); 493 - if (ret != 0) 494 - /* Couldn't enable the subchannel for i/o. Sick device. */ 495 - return ret; 496 - 497 - /* After 60s the device recognition is considered to have failed. */ 498 - ccw_device_set_timeout(cdev, 60*HZ); 433 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 499 434 500 435 /* 501 436 * We used to start here with a sense pgid to find out whether a device ··· 412 537 */ 413 538 cdev->private->flags.recog_done = 0; 414 539 cdev->private->state = DEV_STATE_SENSE_ID; 540 + if (cio_enable_subchannel(sch, (u32) (addr_t) sch)) { 541 + ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER); 542 + return; 543 + } 415 544 ccw_device_sense_id_start(cdev); 416 - return 0; 417 545 } 418 546 419 547 /* 420 - * Handle timeout in device recognition. 548 + * Handle events for states that use the ccw request infrastructure. 421 549 */ 422 - static void 423 - ccw_device_recog_timeout(struct ccw_device *cdev, enum dev_event dev_event) 550 + static void ccw_device_request_event(struct ccw_device *cdev, enum dev_event e) 424 551 { 425 - int ret; 426 - 427 - ret = ccw_device_cancel_halt_clear(cdev); 428 - switch (ret) { 429 - case 0: 430 - ccw_device_recog_done(cdev, DEV_STATE_BOXED); 552 + switch (e) { 553 + case DEV_EVENT_NOTOPER: 554 + ccw_request_notoper(cdev); 431 555 break; 432 - case -ENODEV: 433 - ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER); 556 + case DEV_EVENT_INTERRUPT: 557 + ccw_request_handler(cdev); 558 + break; 559 + case DEV_EVENT_TIMEOUT: 560 + ccw_request_timeout(cdev); 434 561 break; 435 562 default: 436 - ccw_device_set_timeout(cdev, 3*HZ); 563 + break; 437 564 } 438 565 } 439 - 440 566 441 567 void 442 568 ccw_device_verify_done(struct ccw_device *cdev, int err) ··· 447 571 sch = to_subchannel(cdev->dev.parent); 448 572 /* Update schib - pom may have changed. */ 449 573 if (cio_update_schib(sch)) { 450 - cdev->private->flags.donotify = 0; 451 - ccw_device_done(cdev, DEV_STATE_NOT_OPER); 452 - return; 574 + err = -ENODEV; 575 + goto callback; 453 576 } 454 577 /* Update lpm with verified path mask. */ 455 578 sch->lpm = sch->vpm; 456 579 /* Repeat path verification? */ 457 580 if (cdev->private->flags.doverify) { 458 - cdev->private->flags.doverify = 0; 459 581 ccw_device_verify_start(cdev); 460 582 return; 461 583 } 584 + callback: 462 585 switch (err) { 463 - case -EOPNOTSUPP: /* path grouping not supported, just set online. */ 464 - cdev->private->options.pgroup = 0; 465 586 case 0: 466 587 ccw_device_done(cdev, DEV_STATE_ONLINE); 467 588 /* Deliver fake irb to device driver, if needed. */ ··· 477 604 } 478 605 break; 479 606 case -ETIME: 607 + case -EUSERS: 480 608 /* Reset oper notify indication after verify error. */ 481 609 cdev->private->flags.donotify = 0; 482 610 ccw_device_done(cdev, DEV_STATE_BOXED); 483 611 break; 612 + case -EACCES: 613 + /* Reset oper notify indication after verify error. */ 614 + cdev->private->flags.donotify = 0; 615 + ccw_device_done(cdev, DEV_STATE_DISCONNECTED); 616 + break; 484 617 default: 485 618 /* Reset oper notify indication after verify error. */ 486 619 cdev->private->flags.donotify = 0; 487 - if (cdev->online) { 488 - ccw_device_set_timeout(cdev, 0); 489 - dev_fsm_event(cdev, DEV_EVENT_NOTOPER); 490 - } else 491 - ccw_device_done(cdev, DEV_STATE_NOT_OPER); 620 + ccw_device_done(cdev, DEV_STATE_NOT_OPER); 492 621 break; 493 622 } 494 623 } ··· 515 640 dev_fsm_event(cdev, DEV_EVENT_NOTOPER); 516 641 return ret; 517 642 } 518 - /* Do we want to do path grouping? */ 519 - if (!cdev->private->options.pgroup) { 520 - /* Start initial path verification. */ 521 - cdev->private->state = DEV_STATE_VERIFY; 522 - cdev->private->flags.doverify = 0; 523 - ccw_device_verify_start(cdev); 524 - return 0; 525 - } 526 - /* Do a SensePGID first. */ 527 - cdev->private->state = DEV_STATE_SENSE_PGID; 528 - ccw_device_sense_pgid_start(cdev); 643 + /* Start initial path verification. */ 644 + cdev->private->state = DEV_STATE_VERIFY; 645 + ccw_device_verify_start(cdev); 529 646 return 0; 530 647 } 531 648 ··· 533 666 break; 534 667 default: 535 668 cdev->private->flags.donotify = 0; 536 - dev_fsm_event(cdev, DEV_EVENT_NOTOPER); 537 669 ccw_device_done(cdev, DEV_STATE_NOT_OPER); 538 670 break; 539 671 } ··· 569 703 if (cdev->private->state != DEV_STATE_ONLINE) 570 704 return -EINVAL; 571 705 /* Are we doing path grouping? */ 572 - if (!cdev->private->options.pgroup) { 706 + if (!cdev->private->flags.pgroup) { 573 707 /* No, set state offline immediately. */ 574 708 ccw_device_done(cdev, DEV_STATE_OFFLINE); 575 709 return 0; ··· 581 715 } 582 716 583 717 /* 584 - * Handle timeout in device online/offline process. 585 - */ 586 - static void 587 - ccw_device_onoff_timeout(struct ccw_device *cdev, enum dev_event dev_event) 588 - { 589 - int ret; 590 - 591 - ret = ccw_device_cancel_halt_clear(cdev); 592 - switch (ret) { 593 - case 0: 594 - ccw_device_done(cdev, DEV_STATE_BOXED); 595 - break; 596 - case -ENODEV: 597 - ccw_device_done(cdev, DEV_STATE_NOT_OPER); 598 - break; 599 - default: 600 - ccw_device_set_timeout(cdev, 3*HZ); 601 - } 602 - } 603 - 604 - /* 605 - * Handle not oper event in device recognition. 606 - */ 607 - static void 608 - ccw_device_recog_notoper(struct ccw_device *cdev, enum dev_event dev_event) 609 - { 610 - ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER); 611 - } 612 - 613 - /* 614 718 * Handle not operational event in non-special state. 615 719 */ 616 720 static void ccw_device_generic_notoper(struct ccw_device *cdev, 617 721 enum dev_event dev_event) 618 722 { 619 723 if (!ccw_device_notify(cdev, CIO_GONE)) 620 - ccw_device_schedule_sch_unregister(cdev); 724 + ccw_device_sched_todo(cdev, CDEV_TODO_UNREG); 621 725 else 622 726 ccw_device_set_disconnected(cdev); 623 727 } ··· 638 802 } 639 803 /* Device is idle, we can do the path verification. */ 640 804 cdev->private->state = DEV_STATE_VERIFY; 641 - cdev->private->flags.doverify = 0; 642 805 ccw_device_verify_start(cdev); 806 + } 807 + 808 + /* 809 + * Handle path verification event in boxed state. 810 + */ 811 + static void ccw_device_boxed_verify(struct ccw_device *cdev, 812 + enum dev_event dev_event) 813 + { 814 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 815 + 816 + if (cdev->online) { 817 + if (cio_enable_subchannel(sch, (u32) (addr_t) sch)) 818 + ccw_device_done(cdev, DEV_STATE_NOT_OPER); 819 + else 820 + ccw_device_online_verify(cdev, dev_event); 821 + } else 822 + css_schedule_eval(sch->schid); 643 823 } 644 824 645 825 /* ··· 756 904 */ 757 905 if (scsw_fctl(&irb->scsw) & 758 906 (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) { 759 - /* Retry Basic Sense if requested. */ 760 - if (cdev->private->flags.intretry) { 761 - cdev->private->flags.intretry = 0; 762 - ccw_device_do_sense(cdev, irb); 763 - return; 764 - } 765 907 cdev->private->flags.dosense = 0; 766 908 memset(&cdev->private->irb, 0, sizeof(struct irb)); 767 909 ccw_device_accumulate_irb(cdev, irb); ··· 776 930 if (ccw_device_call_handler(cdev) && cdev->private->flags.doverify) 777 931 /* Start delayed path verification. */ 778 932 ccw_device_online_verify(cdev, 0); 779 - } 780 - 781 - static void 782 - ccw_device_clear_verify(struct ccw_device *cdev, enum dev_event dev_event) 783 - { 784 - struct irb *irb; 785 - 786 - irb = (struct irb *) __LC_IRB; 787 - /* Accumulate status. We don't do basic sense. */ 788 - ccw_device_accumulate_irb(cdev, irb); 789 - /* Remember to clear irb to avoid residuals. */ 790 - memset(&cdev->private->irb, 0, sizeof(struct irb)); 791 - /* Try to start delayed device verification. */ 792 - ccw_device_online_verify(cdev, 0); 793 - /* Note: Don't call handler for cio initiated clear! */ 794 933 } 795 934 796 935 static void ··· 835 1004 } 836 1005 837 1006 static void 838 - ccw_device_stlck_done(struct ccw_device *cdev, enum dev_event dev_event) 839 - { 840 - struct irb *irb; 841 - 842 - switch (dev_event) { 843 - case DEV_EVENT_INTERRUPT: 844 - irb = (struct irb *) __LC_IRB; 845 - /* Check for unsolicited interrupt. */ 846 - if ((scsw_stctl(&irb->scsw) == 847 - (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) && 848 - (!scsw_cc(&irb->scsw))) 849 - /* FIXME: we should restart stlck here, but this 850 - * is extremely unlikely ... */ 851 - goto out_wakeup; 852 - 853 - ccw_device_accumulate_irb(cdev, irb); 854 - /* We don't care about basic sense etc. */ 855 - break; 856 - default: /* timeout */ 857 - break; 858 - } 859 - out_wakeup: 860 - wake_up(&cdev->private->wait_q); 861 - } 862 - 863 - static void 864 1007 ccw_device_start_id(struct ccw_device *cdev, enum dev_event dev_event) 865 1008 { 866 1009 struct subchannel *sch; ··· 843 1038 if (cio_enable_subchannel(sch, (u32)(addr_t)sch) != 0) 844 1039 /* Couldn't enable the subchannel for i/o. Sick device. */ 845 1040 return; 846 - 847 - /* After 60s the device recognition is considered to have failed. */ 848 - ccw_device_set_timeout(cdev, 60*HZ); 849 - 850 1041 cdev->private->state = DEV_STATE_DISCONNECTED_SENSE_ID; 851 1042 ccw_device_sense_id_start(cdev); 852 1043 } ··· 873 1072 874 1073 /* We should also udate ssd info, but this has to wait. */ 875 1074 /* Check if this is another device which appeared on the same sch. */ 876 - if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) { 877 - PREPARE_WORK(&cdev->private->kick_work, 878 - ccw_device_move_to_orphanage); 879 - queue_work(slow_path_wq, &cdev->private->kick_work); 880 - } else 1075 + if (sch->schib.pmcw.dev != cdev->private->dev_id.devno) 1076 + css_schedule_eval(sch->schid); 1077 + else 881 1078 ccw_device_start_id(cdev, 0); 882 1079 } 883 1080 884 - static void 885 - ccw_device_offline_irq(struct ccw_device *cdev, enum dev_event dev_event) 1081 + static void ccw_device_disabled_irq(struct ccw_device *cdev, 1082 + enum dev_event dev_event) 886 1083 { 887 1084 struct subchannel *sch; 888 1085 889 1086 sch = to_subchannel(cdev->dev.parent); 890 1087 /* 891 - * An interrupt in state offline means a previous disable was not 1088 + * An interrupt in a disabled state means a previous disable was not 892 1089 * successful - should not happen, but we try to disable again. 893 1090 */ 894 1091 cio_disable_subchannel(sch); ··· 912 1113 ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event) 913 1114 { 914 1115 ccw_device_set_timeout(cdev, 0); 915 - if (dev_event == DEV_EVENT_NOTOPER) 916 - cdev->private->state = DEV_STATE_NOT_OPER; 917 - else 918 - cdev->private->state = DEV_STATE_OFFLINE; 1116 + cdev->private->state = DEV_STATE_NOT_OPER; 919 1117 wake_up(&cdev->private->wait_q); 920 1118 } 921 1119 ··· 922 1126 int ret; 923 1127 924 1128 ret = ccw_device_cancel_halt_clear(cdev); 925 - switch (ret) { 926 - case 0: 927 - cdev->private->state = DEV_STATE_OFFLINE; 928 - wake_up(&cdev->private->wait_q); 929 - break; 930 - case -ENODEV: 1129 + if (ret == -EBUSY) { 1130 + ccw_device_set_timeout(cdev, HZ/10); 1131 + } else { 931 1132 cdev->private->state = DEV_STATE_NOT_OPER; 932 1133 wake_up(&cdev->private->wait_q); 933 - break; 934 - default: 935 - ccw_device_set_timeout(cdev, HZ/10); 936 1134 } 937 1135 } 938 1136 ··· 940 1150 } 941 1151 942 1152 /* 943 - * Bug operation action. 944 - */ 945 - static void 946 - ccw_device_bug(struct ccw_device *cdev, enum dev_event dev_event) 947 - { 948 - CIO_MSG_EVENT(0, "Internal state [%i][%i] not handled for device " 949 - "0.%x.%04x\n", cdev->private->state, dev_event, 950 - cdev->private->dev_id.ssid, 951 - cdev->private->dev_id.devno); 952 - BUG(); 953 - } 954 - 955 - /* 956 1153 * device statemachine 957 1154 */ 958 1155 fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { 959 1156 [DEV_STATE_NOT_OPER] = { 960 1157 [DEV_EVENT_NOTOPER] = ccw_device_nop, 961 - [DEV_EVENT_INTERRUPT] = ccw_device_bug, 1158 + [DEV_EVENT_INTERRUPT] = ccw_device_disabled_irq, 962 1159 [DEV_EVENT_TIMEOUT] = ccw_device_nop, 963 1160 [DEV_EVENT_VERIFY] = ccw_device_nop, 964 1161 }, 965 1162 [DEV_STATE_SENSE_PGID] = { 966 - [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, 967 - [DEV_EVENT_INTERRUPT] = ccw_device_sense_pgid_irq, 968 - [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, 1163 + [DEV_EVENT_NOTOPER] = ccw_device_request_event, 1164 + [DEV_EVENT_INTERRUPT] = ccw_device_request_event, 1165 + [DEV_EVENT_TIMEOUT] = ccw_device_request_event, 969 1166 [DEV_EVENT_VERIFY] = ccw_device_nop, 970 1167 }, 971 1168 [DEV_STATE_SENSE_ID] = { 972 - [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper, 973 - [DEV_EVENT_INTERRUPT] = ccw_device_sense_id_irq, 974 - [DEV_EVENT_TIMEOUT] = ccw_device_recog_timeout, 1169 + [DEV_EVENT_NOTOPER] = ccw_device_request_event, 1170 + [DEV_EVENT_INTERRUPT] = ccw_device_request_event, 1171 + [DEV_EVENT_TIMEOUT] = ccw_device_request_event, 975 1172 [DEV_EVENT_VERIFY] = ccw_device_nop, 976 1173 }, 977 1174 [DEV_STATE_OFFLINE] = { 978 1175 [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, 979 - [DEV_EVENT_INTERRUPT] = ccw_device_offline_irq, 1176 + [DEV_EVENT_INTERRUPT] = ccw_device_disabled_irq, 980 1177 [DEV_EVENT_TIMEOUT] = ccw_device_nop, 981 1178 [DEV_EVENT_VERIFY] = ccw_device_offline_verify, 982 1179 }, 983 1180 [DEV_STATE_VERIFY] = { 984 - [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, 985 - [DEV_EVENT_INTERRUPT] = ccw_device_verify_irq, 986 - [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, 1181 + [DEV_EVENT_NOTOPER] = ccw_device_request_event, 1182 + [DEV_EVENT_INTERRUPT] = ccw_device_request_event, 1183 + [DEV_EVENT_TIMEOUT] = ccw_device_request_event, 987 1184 [DEV_EVENT_VERIFY] = ccw_device_delay_verify, 988 1185 }, 989 1186 [DEV_STATE_ONLINE] = { ··· 986 1209 [DEV_EVENT_VERIFY] = ccw_device_online_verify, 987 1210 }, 988 1211 [DEV_STATE_DISBAND_PGID] = { 989 - [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, 990 - [DEV_EVENT_INTERRUPT] = ccw_device_disband_irq, 991 - [DEV_EVENT_TIMEOUT] = ccw_device_onoff_timeout, 1212 + [DEV_EVENT_NOTOPER] = ccw_device_request_event, 1213 + [DEV_EVENT_INTERRUPT] = ccw_device_request_event, 1214 + [DEV_EVENT_TIMEOUT] = ccw_device_request_event, 992 1215 [DEV_EVENT_VERIFY] = ccw_device_nop, 993 1216 }, 994 1217 [DEV_STATE_BOXED] = { 995 1218 [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, 996 - [DEV_EVENT_INTERRUPT] = ccw_device_stlck_done, 997 - [DEV_EVENT_TIMEOUT] = ccw_device_stlck_done, 998 - [DEV_EVENT_VERIFY] = ccw_device_nop, 1219 + [DEV_EVENT_INTERRUPT] = ccw_device_nop, 1220 + [DEV_EVENT_TIMEOUT] = ccw_device_nop, 1221 + [DEV_EVENT_VERIFY] = ccw_device_boxed_verify, 999 1222 }, 1000 1223 /* states to wait for i/o completion before doing something */ 1001 - [DEV_STATE_CLEAR_VERIFY] = { 1002 - [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, 1003 - [DEV_EVENT_INTERRUPT] = ccw_device_clear_verify, 1004 - [DEV_EVENT_TIMEOUT] = ccw_device_nop, 1005 - [DEV_EVENT_VERIFY] = ccw_device_nop, 1006 - }, 1007 1224 [DEV_STATE_TIMEOUT_KILL] = { 1008 1225 [DEV_EVENT_NOTOPER] = ccw_device_generic_notoper, 1009 1226 [DEV_EVENT_INTERRUPT] = ccw_device_killing_irq, ··· 1014 1243 [DEV_STATE_DISCONNECTED] = { 1015 1244 [DEV_EVENT_NOTOPER] = ccw_device_nop, 1016 1245 [DEV_EVENT_INTERRUPT] = ccw_device_start_id, 1017 - [DEV_EVENT_TIMEOUT] = ccw_device_bug, 1246 + [DEV_EVENT_TIMEOUT] = ccw_device_nop, 1018 1247 [DEV_EVENT_VERIFY] = ccw_device_start_id, 1019 1248 }, 1020 1249 [DEV_STATE_DISCONNECTED_SENSE_ID] = { 1021 - [DEV_EVENT_NOTOPER] = ccw_device_recog_notoper, 1022 - [DEV_EVENT_INTERRUPT] = ccw_device_sense_id_irq, 1023 - [DEV_EVENT_TIMEOUT] = ccw_device_recog_timeout, 1250 + [DEV_EVENT_NOTOPER] = ccw_device_request_event, 1251 + [DEV_EVENT_INTERRUPT] = ccw_device_request_event, 1252 + [DEV_EVENT_TIMEOUT] = ccw_device_request_event, 1024 1253 [DEV_EVENT_VERIFY] = ccw_device_nop, 1025 1254 }, 1026 1255 [DEV_STATE_CMFCHANGE] = { ··· 1034 1263 [DEV_EVENT_INTERRUPT] = ccw_device_update_cmfblock, 1035 1264 [DEV_EVENT_TIMEOUT] = ccw_device_update_cmfblock, 1036 1265 [DEV_EVENT_VERIFY] = ccw_device_update_cmfblock, 1266 + }, 1267 + [DEV_STATE_STEAL_LOCK] = { 1268 + [DEV_EVENT_NOTOPER] = ccw_device_request_event, 1269 + [DEV_EVENT_INTERRUPT] = ccw_device_request_event, 1270 + [DEV_EVENT_TIMEOUT] = ccw_device_request_event, 1271 + [DEV_EVENT_VERIFY] = ccw_device_nop, 1037 1272 }, 1038 1273 }; 1039 1274
+138 -239
drivers/s390/cio/device_id.c
··· 1 1 /* 2 - * drivers/s390/cio/device_id.c 2 + * CCW device SENSE ID I/O handling. 3 3 * 4 - * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, 5 - * IBM Corporation 6 - * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com) 7 - * Martin Schwidefsky (schwidefsky@de.ibm.com) 8 - * 9 - * Sense ID functions. 4 + * Copyright IBM Corp. 2002,2009 5 + * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> 6 + * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 + * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> 10 8 */ 11 9 12 - #include <linux/module.h> 13 - #include <linux/init.h> 14 10 #include <linux/kernel.h> 15 - 11 + #include <linux/string.h> 12 + #include <linux/types.h> 13 + #include <linux/errno.h> 16 14 #include <asm/ccwdev.h> 17 - #include <asm/delay.h> 15 + #include <asm/setup.h> 18 16 #include <asm/cio.h> 19 - #include <asm/lowcore.h> 20 17 #include <asm/diag.h> 21 18 22 19 #include "cio.h" 23 20 #include "cio_debug.h" 24 - #include "css.h" 25 21 #include "device.h" 26 - #include "ioasm.h" 27 22 #include "io_sch.h" 28 23 24 + #define SENSE_ID_RETRIES 256 25 + #define SENSE_ID_TIMEOUT (10 * HZ) 26 + #define SENSE_ID_MIN_LEN 4 27 + #define SENSE_ID_BASIC_LEN 7 28 + 29 29 /** 30 - * vm_vdev_to_cu_type - Convert vm virtual device into control unit type 31 - * for certain devices. 32 - * @class: virtual device class 33 - * @type: virtual device type 30 + * diag210_to_senseid - convert diag 0x210 data to sense id information 31 + * @senseid: sense id 32 + * @diag: diag 0x210 data 34 33 * 35 - * Returns control unit type if a match was made or %0xffff otherwise. 34 + * Return 0 on success, non-zero otherwise. 36 35 */ 37 - static int vm_vdev_to_cu_type(int class, int type) 36 + static int diag210_to_senseid(struct senseid *senseid, struct diag210 *diag) 38 37 { 39 38 static struct { 40 39 int class, type, cu_type; ··· 70 71 }; 71 72 int i; 72 73 73 - for (i = 0; i < ARRAY_SIZE(vm_devices); i++) 74 - if (class == vm_devices[i].class && type == vm_devices[i].type) 75 - return vm_devices[i].cu_type; 76 - 77 - return 0xffff; 78 - } 79 - 80 - /** 81 - * diag_get_dev_info - retrieve device information via DIAG X'210' 82 - * @devno: device number 83 - * @ps: pointer to sense ID data area 84 - * 85 - * Returns zero on success, non-zero otherwise. 86 - */ 87 - static int diag_get_dev_info(u16 devno, struct senseid *ps) 88 - { 89 - struct diag210 diag_data; 90 - int ccode; 91 - 92 - CIO_TRACE_EVENT (4, "VMvdinf"); 93 - 94 - diag_data = (struct diag210) { 95 - .vrdcdvno = devno, 96 - .vrdclen = sizeof (diag_data), 97 - }; 98 - 99 - ccode = diag210 (&diag_data); 100 - if ((ccode == 0) || (ccode == 2)) { 101 - ps->reserved = 0xff; 102 - 103 - /* Special case for osa devices. */ 104 - if (diag_data.vrdcvcla == 0x02 && diag_data.vrdcvtyp == 0x20) { 105 - ps->cu_type = 0x3088; 106 - ps->cu_model = 0x60; 74 + /* Special case for osa devices. */ 75 + if (diag->vrdcvcla == 0x02 && diag->vrdcvtyp == 0x20) { 76 + senseid->cu_type = 0x3088; 77 + senseid->cu_model = 0x60; 78 + senseid->reserved = 0xff; 79 + return 0; 80 + } 81 + for (i = 0; i < ARRAY_SIZE(vm_devices); i++) { 82 + if (diag->vrdcvcla == vm_devices[i].class && 83 + diag->vrdcvtyp == vm_devices[i].type) { 84 + senseid->cu_type = vm_devices[i].cu_type; 85 + senseid->reserved = 0xff; 107 86 return 0; 108 87 } 109 - ps->cu_type = vm_vdev_to_cu_type(diag_data.vrdcvcla, 110 - diag_data.vrdcvtyp); 111 - if (ps->cu_type != 0xffff) 112 - return 0; 113 88 } 114 - 115 - CIO_MSG_EVENT(0, "DIAG X'210' for device %04X returned (cc = %d):" 116 - "vdev class : %02X, vdev type : %04X \n ... " 117 - "rdev class : %02X, rdev type : %04X, " 118 - "rdev model: %02X\n", 119 - devno, ccode, 120 - diag_data.vrdcvcla, diag_data.vrdcvtyp, 121 - diag_data.vrdcrccl, diag_data.vrdccrty, 122 - diag_data.vrdccrmd); 123 89 124 90 return -ENODEV; 125 91 } 126 92 127 - /* 128 - * Start Sense ID helper function. 129 - * Try to obtain the 'control unit'/'device type' information 130 - * associated with the subchannel. 93 + /** 94 + * diag_get_dev_info - retrieve device information via diag 0x210 95 + * @cdev: ccw device 96 + * 97 + * Returns zero on success, non-zero otherwise. 131 98 */ 132 - static int 133 - __ccw_device_sense_id_start(struct ccw_device *cdev) 99 + static int diag210_get_dev_info(struct ccw_device *cdev) 134 100 { 135 - struct subchannel *sch; 136 - struct ccw1 *ccw; 137 - int ret; 101 + struct ccw_dev_id *dev_id = &cdev->private->dev_id; 102 + struct senseid *senseid = &cdev->private->senseid; 103 + struct diag210 diag_data; 104 + int rc; 138 105 139 - sch = to_subchannel(cdev->dev.parent); 140 - /* Setup sense channel program. */ 141 - ccw = cdev->private->iccws; 142 - ccw->cmd_code = CCW_CMD_SENSE_ID; 143 - ccw->cda = (__u32) __pa (&cdev->private->senseid); 144 - ccw->count = sizeof (struct senseid); 145 - ccw->flags = CCW_FLAG_SLI; 106 + if (dev_id->ssid != 0) 107 + return -ENODEV; 108 + memset(&diag_data, 0, sizeof(diag_data)); 109 + diag_data.vrdcdvno = dev_id->devno; 110 + diag_data.vrdclen = sizeof(diag_data); 111 + rc = diag210(&diag_data); 112 + CIO_TRACE_EVENT(4, "diag210"); 113 + CIO_HEX_EVENT(4, &rc, sizeof(rc)); 114 + CIO_HEX_EVENT(4, &diag_data, sizeof(diag_data)); 115 + if (rc != 0 && rc != 2) 116 + goto err_failed; 117 + if (diag210_to_senseid(senseid, &diag_data)) 118 + goto err_unknown; 119 + return 0; 146 120 147 - /* Reset device status. */ 148 - memset(&cdev->private->irb, 0, sizeof(struct irb)); 149 - 150 - /* Try on every path. */ 151 - ret = -ENODEV; 152 - while (cdev->private->imask != 0) { 153 - cdev->private->senseid.cu_type = 0xFFFF; 154 - if ((sch->opm & cdev->private->imask) != 0 && 155 - cdev->private->iretry > 0) { 156 - cdev->private->iretry--; 157 - /* Reset internal retry indication. */ 158 - cdev->private->flags.intretry = 0; 159 - ret = cio_start (sch, cdev->private->iccws, 160 - cdev->private->imask); 161 - /* ret is 0, -EBUSY, -EACCES or -ENODEV */ 162 - if (ret != -EACCES) 163 - return ret; 164 - } 165 - cdev->private->imask >>= 1; 166 - cdev->private->iretry = 5; 167 - } 168 - return ret; 169 - } 170 - 171 - void 172 - ccw_device_sense_id_start(struct ccw_device *cdev) 173 - { 174 - int ret; 175 - 176 - memset (&cdev->private->senseid, 0, sizeof (struct senseid)); 177 - cdev->private->imask = 0x80; 178 - cdev->private->iretry = 5; 179 - ret = __ccw_device_sense_id_start(cdev); 180 - if (ret && ret != -EBUSY) 181 - ccw_device_sense_id_done(cdev, ret); 121 + err_unknown: 122 + CIO_MSG_EVENT(0, "snsid: device 0.%x.%04x: unknown diag210 data\n", 123 + dev_id->ssid, dev_id->devno); 124 + return -ENODEV; 125 + err_failed: 126 + CIO_MSG_EVENT(0, "snsid: device 0.%x.%04x: diag210 failed (rc=%d)\n", 127 + dev_id->ssid, dev_id->devno, rc); 128 + return -ENODEV; 182 129 } 183 130 184 131 /* 185 - * Called from interrupt context to check if a valid answer 186 - * to Sense ID was received. 132 + * Initialize SENSE ID data. 187 133 */ 188 - static int 189 - ccw_device_check_sense_id(struct ccw_device *cdev) 134 + static void snsid_init(struct ccw_device *cdev) 190 135 { 191 - struct subchannel *sch; 192 - struct irb *irb; 136 + cdev->private->flags.esid = 0; 137 + memset(&cdev->private->senseid, 0, sizeof(cdev->private->senseid)); 138 + cdev->private->senseid.cu_type = 0xffff; 139 + } 193 140 194 - sch = to_subchannel(cdev->dev.parent); 195 - irb = &cdev->private->irb; 141 + /* 142 + * Check for complete SENSE ID data. 143 + */ 144 + static int snsid_check(struct ccw_device *cdev, void *data) 145 + { 146 + struct cmd_scsw *scsw = &cdev->private->irb.scsw.cmd; 147 + int len = sizeof(struct senseid) - scsw->count; 196 148 197 - /* Check the error cases. */ 198 - if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { 199 - /* Retry Sense ID if requested. */ 200 - if (cdev->private->flags.intretry) { 201 - cdev->private->flags.intretry = 0; 202 - return -EAGAIN; 203 - } 204 - return -ETIME; 205 - } 206 - if (irb->esw.esw0.erw.cons && (irb->ecw[0] & SNS0_CMD_REJECT)) { 207 - /* 208 - * if the device doesn't support the SenseID 209 - * command further retries wouldn't help ... 210 - * NB: We don't check here for intervention required like we 211 - * did before, because tape devices with no tape inserted 212 - * may present this status *in conjunction with* the 213 - * sense id information. So, for intervention required, 214 - * we use the "whack it until it talks" strategy... 215 - */ 216 - CIO_MSG_EVENT(0, "SenseID : device %04x on Subchannel " 217 - "0.%x.%04x reports cmd reject\n", 218 - cdev->private->dev_id.devno, sch->schid.ssid, 219 - sch->schid.sch_no); 149 + /* Check for incomplete SENSE ID data. */ 150 + if (len < SENSE_ID_MIN_LEN) 151 + goto out_restart; 152 + if (cdev->private->senseid.cu_type == 0xffff) 153 + goto out_restart; 154 + /* Check for incompatible SENSE ID data. */ 155 + if (cdev->private->senseid.reserved != 0xff) 220 156 return -EOPNOTSUPP; 221 - } 222 - if (irb->esw.esw0.erw.cons) { 223 - CIO_MSG_EVENT(2, "SenseID : UC on dev 0.%x.%04x, " 224 - "lpum %02X, cnt %02d, sns :" 225 - " %02X%02X%02X%02X %02X%02X%02X%02X ...\n", 226 - cdev->private->dev_id.ssid, 227 - cdev->private->dev_id.devno, 228 - irb->esw.esw0.sublog.lpum, 229 - irb->esw.esw0.erw.scnt, 230 - irb->ecw[0], irb->ecw[1], 231 - irb->ecw[2], irb->ecw[3], 232 - irb->ecw[4], irb->ecw[5], 233 - irb->ecw[6], irb->ecw[7]); 234 - return -EAGAIN; 235 - } 236 - if (irb->scsw.cmd.cc == 3) { 237 - u8 lpm; 157 + /* Check for extended-identification information. */ 158 + if (len > SENSE_ID_BASIC_LEN) 159 + cdev->private->flags.esid = 1; 160 + return 0; 238 161 239 - lpm = to_io_private(sch)->orb.cmd.lpm; 240 - if ((lpm & sch->schib.pmcw.pim & sch->schib.pmcw.pam) != 0) 241 - CIO_MSG_EVENT(4, "SenseID : path %02X for device %04x " 242 - "on subchannel 0.%x.%04x is " 243 - "'not operational'\n", lpm, 244 - cdev->private->dev_id.devno, 245 - sch->schid.ssid, sch->schid.sch_no); 246 - return -EACCES; 247 - } 248 - 249 - /* Did we get a proper answer ? */ 250 - if (irb->scsw.cmd.cc == 0 && cdev->private->senseid.cu_type != 0xFFFF && 251 - cdev->private->senseid.reserved == 0xFF) { 252 - if (irb->scsw.cmd.count < sizeof(struct senseid) - 8) 253 - cdev->private->flags.esid = 1; 254 - return 0; /* Success */ 255 - } 256 - 257 - /* Hmm, whatever happened, try again. */ 258 - CIO_MSG_EVENT(2, "SenseID : start_IO() for device %04x on " 259 - "subchannel 0.%x.%04x returns status %02X%02X\n", 260 - cdev->private->dev_id.devno, sch->schid.ssid, 261 - sch->schid.sch_no, 262 - irb->scsw.cmd.dstat, irb->scsw.cmd.cstat); 162 + out_restart: 163 + snsid_init(cdev); 263 164 return -EAGAIN; 264 165 } 265 166 266 167 /* 267 - * Got interrupt for Sense ID. 168 + * Process SENSE ID request result. 268 169 */ 269 - void 270 - ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) 170 + static void snsid_callback(struct ccw_device *cdev, void *data, int rc) 271 171 { 272 - struct subchannel *sch; 273 - struct irb *irb; 274 - int ret; 172 + struct ccw_dev_id *id = &cdev->private->dev_id; 173 + struct senseid *senseid = &cdev->private->senseid; 174 + int vm = 0; 275 175 276 - sch = to_subchannel(cdev->dev.parent); 277 - irb = (struct irb *) __LC_IRB; 278 - /* Retry sense id, if needed. */ 279 - if (irb->scsw.cmd.stctl == 280 - (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { 281 - if ((irb->scsw.cmd.cc == 1) || !irb->scsw.cmd.actl) { 282 - ret = __ccw_device_sense_id_start(cdev); 283 - if (ret && ret != -EBUSY) 284 - ccw_device_sense_id_done(cdev, ret); 176 + if (rc && MACHINE_IS_VM) { 177 + /* Try diag 0x210 fallback on z/VM. */ 178 + snsid_init(cdev); 179 + if (diag210_get_dev_info(cdev) == 0) { 180 + rc = 0; 181 + vm = 1; 285 182 } 286 - return; 287 183 } 288 - if (ccw_device_accumulate_and_sense(cdev, irb) != 0) 289 - return; 290 - ret = ccw_device_check_sense_id(cdev); 291 - memset(&cdev->private->irb, 0, sizeof(struct irb)); 292 - switch (ret) { 293 - /* 0, -ETIME, -EOPNOTSUPP, -EAGAIN or -EACCES */ 294 - case 0: /* Sense id succeeded. */ 295 - case -ETIME: /* Sense id stopped by timeout. */ 296 - ccw_device_sense_id_done(cdev, ret); 297 - break; 298 - case -EACCES: /* channel is not operational. */ 299 - sch->lpm &= ~cdev->private->imask; 300 - cdev->private->imask >>= 1; 301 - cdev->private->iretry = 5; 302 - /* fall through. */ 303 - case -EAGAIN: /* try again. */ 304 - ret = __ccw_device_sense_id_start(cdev); 305 - if (ret == 0 || ret == -EBUSY) 306 - break; 307 - /* fall through. */ 308 - default: /* Sense ID failed. Try asking VM. */ 309 - if (MACHINE_IS_VM) 310 - ret = diag_get_dev_info(cdev->private->dev_id.devno, 311 - &cdev->private->senseid); 312 - else 313 - /* 314 - * If we can't couldn't identify the device type we 315 - * consider the device "not operational". 316 - */ 317 - ret = -ENODEV; 184 + CIO_MSG_EVENT(2, "snsid: device 0.%x.%04x: rc=%d %04x/%02x " 185 + "%04x/%02x%s\n", id->ssid, id->devno, rc, 186 + senseid->cu_type, senseid->cu_model, senseid->dev_type, 187 + senseid->dev_model, vm ? " (diag210)" : ""); 188 + ccw_device_sense_id_done(cdev, rc); 189 + } 318 190 319 - ccw_device_sense_id_done(cdev, ret); 320 - break; 321 - } 191 + /** 192 + * ccw_device_sense_id_start - perform SENSE ID 193 + * @cdev: ccw device 194 + * 195 + * Execute a SENSE ID channel program on @cdev to update its sense id 196 + * information. When finished, call ccw_device_sense_id_done with a 197 + * return code specifying the result. 198 + */ 199 + void ccw_device_sense_id_start(struct ccw_device *cdev) 200 + { 201 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 202 + struct ccw_request *req = &cdev->private->req; 203 + struct ccw1 *cp = cdev->private->iccws; 204 + 205 + CIO_TRACE_EVENT(4, "snsid"); 206 + CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); 207 + /* Data setup. */ 208 + snsid_init(cdev); 209 + /* Channel program setup. */ 210 + cp->cmd_code = CCW_CMD_SENSE_ID; 211 + cp->cda = (u32) (addr_t) &cdev->private->senseid; 212 + cp->count = sizeof(struct senseid); 213 + cp->flags = CCW_FLAG_SLI; 214 + /* Request setup. */ 215 + memset(req, 0, sizeof(*req)); 216 + req->cp = cp; 217 + req->timeout = SENSE_ID_TIMEOUT; 218 + req->maxretries = SENSE_ID_RETRIES; 219 + req->lpm = sch->schib.pmcw.pam & sch->opm; 220 + req->check = snsid_check; 221 + req->callback = snsid_callback; 222 + ccw_request_start(cdev); 322 223 }
+80 -62
drivers/s390/cio/device_ops.c
··· 11 11 #include <linux/list.h> 12 12 #include <linux/device.h> 13 13 #include <linux/delay.h> 14 + #include <linux/completion.h> 14 15 15 16 #include <asm/ccwdev.h> 16 17 #include <asm/idals.h> ··· 47 46 cdev->private->options.repall = (flags & CCWDEV_REPORT_ALL) != 0; 48 47 cdev->private->options.pgroup = (flags & CCWDEV_DO_PATHGROUP) != 0; 49 48 cdev->private->options.force = (flags & CCWDEV_ALLOW_FORCE) != 0; 49 + cdev->private->options.mpath = (flags & CCWDEV_DO_MULTIPATH) != 0; 50 50 return 0; 51 51 } 52 52 ··· 76 74 cdev->private->options.repall |= (flags & CCWDEV_REPORT_ALL) != 0; 77 75 cdev->private->options.pgroup |= (flags & CCWDEV_DO_PATHGROUP) != 0; 78 76 cdev->private->options.force |= (flags & CCWDEV_ALLOW_FORCE) != 0; 77 + cdev->private->options.mpath |= (flags & CCWDEV_DO_MULTIPATH) != 0; 79 78 return 0; 80 79 } 81 80 ··· 93 90 cdev->private->options.repall &= (flags & CCWDEV_REPORT_ALL) == 0; 94 91 cdev->private->options.pgroup &= (flags & CCWDEV_DO_PATHGROUP) == 0; 95 92 cdev->private->options.force &= (flags & CCWDEV_ALLOW_FORCE) == 0; 93 + cdev->private->options.mpath &= (flags & CCWDEV_DO_MULTIPATH) == 0; 96 94 } 95 + 96 + /** 97 + * ccw_device_is_pathgroup - determine if paths to this device are grouped 98 + * @cdev: ccw device 99 + * 100 + * Return non-zero if there is a path group, zero otherwise. 101 + */ 102 + int ccw_device_is_pathgroup(struct ccw_device *cdev) 103 + { 104 + return cdev->private->flags.pgroup; 105 + } 106 + EXPORT_SYMBOL(ccw_device_is_pathgroup); 107 + 108 + /** 109 + * ccw_device_is_multipath - determine if device is operating in multipath mode 110 + * @cdev: ccw device 111 + * 112 + * Return non-zero if device is operating in multipath mode, zero otherwise. 113 + */ 114 + int ccw_device_is_multipath(struct ccw_device *cdev) 115 + { 116 + return cdev->private->flags.mpath; 117 + } 118 + EXPORT_SYMBOL(ccw_device_is_multipath); 97 119 98 120 /** 99 121 * ccw_device_clear() - terminate I/O request processing ··· 195 167 return -EINVAL; 196 168 if (cdev->private->state == DEV_STATE_NOT_OPER) 197 169 return -ENODEV; 198 - if (cdev->private->state == DEV_STATE_VERIFY || 199 - cdev->private->state == DEV_STATE_CLEAR_VERIFY) { 170 + if (cdev->private->state == DEV_STATE_VERIFY) { 200 171 /* Remember to fake irb when finished. */ 201 172 if (!cdev->private->flags.fake_irb) { 202 173 cdev->private->flags.fake_irb = 1; ··· 505 478 return sch->lpm; 506 479 } 507 480 508 - /* 509 - * Try to break the lock on a boxed device. 510 - */ 511 - int 512 - ccw_device_stlck(struct ccw_device *cdev) 481 + struct stlck_data { 482 + struct completion done; 483 + int rc; 484 + }; 485 + 486 + void ccw_device_stlck_done(struct ccw_device *cdev, void *data, int rc) 513 487 { 514 - void *buf, *buf2; 515 - unsigned long flags; 516 - struct subchannel *sch; 517 - int ret; 488 + struct stlck_data *sdata = data; 518 489 519 - if (!cdev) 520 - return -ENODEV; 490 + sdata->rc = rc; 491 + complete(&sdata->done); 492 + } 521 493 522 - if (cdev->drv && !cdev->private->options.force) 523 - return -EINVAL; 494 + /* 495 + * Perform unconditional reserve + release. 496 + */ 497 + int ccw_device_stlck(struct ccw_device *cdev) 498 + { 499 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 500 + struct stlck_data data; 501 + u8 *buffer; 502 + int rc; 524 503 525 - sch = to_subchannel(cdev->dev.parent); 526 - 527 - CIO_TRACE_EVENT(2, "stl lock"); 528 - CIO_TRACE_EVENT(2, dev_name(&cdev->dev)); 529 - 530 - buf = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL); 531 - if (!buf) 532 - return -ENOMEM; 533 - buf2 = kmalloc(32*sizeof(char), GFP_DMA|GFP_KERNEL); 534 - if (!buf2) { 535 - kfree(buf); 536 - return -ENOMEM; 504 + /* Check if steal lock operation is valid for this device. */ 505 + if (cdev->drv) { 506 + if (!cdev->private->options.force) 507 + return -EINVAL; 537 508 } 538 - spin_lock_irqsave(sch->lock, flags); 539 - ret = cio_enable_subchannel(sch, (u32)(addr_t)sch); 540 - if (ret) 509 + buffer = kzalloc(64, GFP_DMA | GFP_KERNEL); 510 + if (!buffer) 511 + return -ENOMEM; 512 + init_completion(&data.done); 513 + data.rc = -EIO; 514 + spin_lock_irq(sch->lock); 515 + rc = cio_enable_subchannel(sch, (u32) (addr_t) sch); 516 + if (rc) 541 517 goto out_unlock; 542 - /* 543 - * Setup ccw. We chain an unconditional reserve and a release so we 544 - * only break the lock. 545 - */ 546 - cdev->private->iccws[0].cmd_code = CCW_CMD_STLCK; 547 - cdev->private->iccws[0].cda = (__u32) __pa(buf); 548 - cdev->private->iccws[0].count = 32; 549 - cdev->private->iccws[0].flags = CCW_FLAG_CC; 550 - cdev->private->iccws[1].cmd_code = CCW_CMD_RELEASE; 551 - cdev->private->iccws[1].cda = (__u32) __pa(buf2); 552 - cdev->private->iccws[1].count = 32; 553 - cdev->private->iccws[1].flags = 0; 554 - ret = cio_start(sch, cdev->private->iccws, 0); 555 - if (ret) { 556 - cio_disable_subchannel(sch); //FIXME: return code? 557 - goto out_unlock; 518 + /* Perform operation. */ 519 + cdev->private->state = DEV_STATE_STEAL_LOCK, 520 + ccw_device_stlck_start(cdev, &data, &buffer[0], &buffer[32]); 521 + spin_unlock_irq(sch->lock); 522 + /* Wait for operation to finish. */ 523 + if (wait_for_completion_interruptible(&data.done)) { 524 + /* Got a signal. */ 525 + spin_lock_irq(sch->lock); 526 + ccw_request_cancel(cdev); 527 + spin_unlock_irq(sch->lock); 528 + wait_for_completion(&data.done); 558 529 } 559 - cdev->private->irb.scsw.cmd.actl |= SCSW_ACTL_START_PEND; 560 - spin_unlock_irqrestore(sch->lock, flags); 561 - wait_event(cdev->private->wait_q, 562 - cdev->private->irb.scsw.cmd.actl == 0); 563 - spin_lock_irqsave(sch->lock, flags); 564 - cio_disable_subchannel(sch); //FIXME: return code? 565 - if ((cdev->private->irb.scsw.cmd.dstat != 566 - (DEV_STAT_CHN_END|DEV_STAT_DEV_END)) || 567 - (cdev->private->irb.scsw.cmd.cstat != 0)) 568 - ret = -EIO; 569 - /* Clear irb. */ 570 - memset(&cdev->private->irb, 0, sizeof(struct irb)); 530 + rc = data.rc; 531 + /* Check results. */ 532 + spin_lock_irq(sch->lock); 533 + cio_disable_subchannel(sch); 534 + cdev->private->state = DEV_STATE_BOXED; 571 535 out_unlock: 572 - kfree(buf); 573 - kfree(buf2); 574 - spin_unlock_irqrestore(sch->lock, flags); 575 - return ret; 536 + spin_unlock_irq(sch->lock); 537 + kfree(buffer); 538 + 539 + return rc; 576 540 } 577 541 578 542 void *ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_no)
+525 -558
drivers/s390/cio/device_pgid.c
··· 1 1 /* 2 - * drivers/s390/cio/device_pgid.c 2 + * CCW device PGID and path verification I/O handling. 3 3 * 4 - * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, 5 - * IBM Corporation 6 - * Author(s): Cornelia Huck (cornelia.huck@de.ibm.com) 7 - * Martin Schwidefsky (schwidefsky@de.ibm.com) 8 - * 9 - * Path Group ID functions. 4 + * Copyright IBM Corp. 2002,2009 5 + * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> 6 + * Martin Schwidefsky <schwidefsky@de.ibm.com> 7 + * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> 10 8 */ 11 9 12 - #include <linux/module.h> 13 - #include <linux/init.h> 14 - 10 + #include <linux/kernel.h> 11 + #include <linux/string.h> 12 + #include <linux/types.h> 13 + #include <linux/errno.h> 14 + #include <linux/bitops.h> 15 15 #include <asm/ccwdev.h> 16 16 #include <asm/cio.h> 17 - #include <asm/delay.h> 18 - #include <asm/lowcore.h> 19 17 20 18 #include "cio.h" 21 19 #include "cio_debug.h" 22 - #include "css.h" 23 20 #include "device.h" 24 - #include "ioasm.h" 25 21 #include "io_sch.h" 26 22 27 - /* 28 - * Helper function called from interrupt context to decide whether an 29 - * operation should be tried again. 30 - */ 31 - static int __ccw_device_should_retry(union scsw *scsw) 32 - { 33 - /* CC is only valid if start function bit is set. */ 34 - if ((scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && scsw->cmd.cc == 1) 35 - return 1; 36 - /* No more activity. For sense and set PGID we stubbornly try again. */ 37 - if (!scsw->cmd.actl) 38 - return 1; 39 - return 0; 40 - } 23 + #define PGID_RETRIES 256 24 + #define PGID_TIMEOUT (10 * HZ) 41 25 42 26 /* 43 - * Start Sense Path Group ID helper function. Used in ccw_device_recog 44 - * and ccw_device_sense_pgid. 27 + * Process path verification data and report result. 45 28 */ 46 - static int 47 - __ccw_device_sense_pgid_start(struct ccw_device *cdev) 48 - { 49 - struct subchannel *sch; 50 - struct ccw1 *ccw; 51 - int ret; 52 - int i; 53 - 54 - sch = to_subchannel(cdev->dev.parent); 55 - /* Return if we already checked on all paths. */ 56 - if (cdev->private->imask == 0) 57 - return (sch->lpm == 0) ? -ENODEV : -EACCES; 58 - i = 8 - ffs(cdev->private->imask); 59 - 60 - /* Setup sense path group id channel program. */ 61 - ccw = cdev->private->iccws; 62 - ccw->cmd_code = CCW_CMD_SENSE_PGID; 63 - ccw->count = sizeof (struct pgid); 64 - ccw->flags = CCW_FLAG_SLI; 65 - 66 - /* Reset device status. */ 67 - memset(&cdev->private->irb, 0, sizeof(struct irb)); 68 - /* Try on every path. */ 69 - ret = -ENODEV; 70 - while (cdev->private->imask != 0) { 71 - /* Try every path multiple times. */ 72 - ccw->cda = (__u32) __pa (&cdev->private->pgid[i]); 73 - if (cdev->private->iretry > 0) { 74 - cdev->private->iretry--; 75 - /* Reset internal retry indication. */ 76 - cdev->private->flags.intretry = 0; 77 - ret = cio_start (sch, cdev->private->iccws, 78 - cdev->private->imask); 79 - /* ret is 0, -EBUSY, -EACCES or -ENODEV */ 80 - if (ret != -EACCES) 81 - return ret; 82 - CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel " 83 - "0.%x.%04x, lpm %02X, became 'not " 84 - "operational'\n", 85 - cdev->private->dev_id.devno, 86 - sch->schid.ssid, 87 - sch->schid.sch_no, cdev->private->imask); 88 - 89 - } 90 - cdev->private->imask >>= 1; 91 - cdev->private->iretry = 5; 92 - i++; 93 - } 94 - 95 - return ret; 96 - } 97 - 98 - void 99 - ccw_device_sense_pgid_start(struct ccw_device *cdev) 100 - { 101 - int ret; 102 - 103 - /* Set a timeout of 60s */ 104 - ccw_device_set_timeout(cdev, 60*HZ); 105 - 106 - cdev->private->state = DEV_STATE_SENSE_PGID; 107 - cdev->private->imask = 0x80; 108 - cdev->private->iretry = 5; 109 - memset (&cdev->private->pgid, 0, sizeof (cdev->private->pgid)); 110 - ret = __ccw_device_sense_pgid_start(cdev); 111 - if (ret && ret != -EBUSY) 112 - ccw_device_sense_pgid_done(cdev, ret); 113 - } 114 - 115 - /* 116 - * Called from interrupt context to check if a valid answer 117 - * to Sense Path Group ID was received. 118 - */ 119 - static int 120 - __ccw_device_check_sense_pgid(struct ccw_device *cdev) 121 - { 122 - struct subchannel *sch; 123 - struct irb *irb; 124 - int i; 125 - 126 - sch = to_subchannel(cdev->dev.parent); 127 - irb = &cdev->private->irb; 128 - if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { 129 - /* Retry Sense PGID if requested. */ 130 - if (cdev->private->flags.intretry) { 131 - cdev->private->flags.intretry = 0; 132 - return -EAGAIN; 133 - } 134 - return -ETIME; 135 - } 136 - if (irb->esw.esw0.erw.cons && 137 - (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) { 138 - /* 139 - * If the device doesn't support the Sense Path Group ID 140 - * command further retries wouldn't help ... 141 - */ 142 - return -EOPNOTSUPP; 143 - } 144 - if (irb->esw.esw0.erw.cons) { 145 - CIO_MSG_EVENT(2, "SNID - device 0.%x.%04x, unit check, " 146 - "lpum %02X, cnt %02d, sns : " 147 - "%02X%02X%02X%02X %02X%02X%02X%02X ...\n", 148 - cdev->private->dev_id.ssid, 149 - cdev->private->dev_id.devno, 150 - irb->esw.esw0.sublog.lpum, 151 - irb->esw.esw0.erw.scnt, 152 - irb->ecw[0], irb->ecw[1], 153 - irb->ecw[2], irb->ecw[3], 154 - irb->ecw[4], irb->ecw[5], 155 - irb->ecw[6], irb->ecw[7]); 156 - return -EAGAIN; 157 - } 158 - if (irb->scsw.cmd.cc == 3) { 159 - u8 lpm; 160 - 161 - lpm = to_io_private(sch)->orb.cmd.lpm; 162 - CIO_MSG_EVENT(3, "SNID - Device %04x on Subchannel 0.%x.%04x," 163 - " lpm %02X, became 'not operational'\n", 164 - cdev->private->dev_id.devno, sch->schid.ssid, 165 - sch->schid.sch_no, lpm); 166 - return -EACCES; 167 - } 168 - i = 8 - ffs(cdev->private->imask); 169 - if (cdev->private->pgid[i].inf.ps.state2 == SNID_STATE2_RESVD_ELSE) { 170 - CIO_MSG_EVENT(2, "SNID - Device %04x on Subchannel 0.%x.%04x " 171 - "is reserved by someone else\n", 172 - cdev->private->dev_id.devno, sch->schid.ssid, 173 - sch->schid.sch_no); 174 - return -EUSERS; 175 - } 176 - return 0; 177 - } 178 - 179 - /* 180 - * Got interrupt for Sense Path Group ID. 181 - */ 182 - void 183 - ccw_device_sense_pgid_irq(struct ccw_device *cdev, enum dev_event dev_event) 184 - { 185 - struct subchannel *sch; 186 - struct irb *irb; 187 - int ret; 188 - 189 - irb = (struct irb *) __LC_IRB; 190 - 191 - if (irb->scsw.cmd.stctl == 192 - (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { 193 - if (__ccw_device_should_retry(&irb->scsw)) { 194 - ret = __ccw_device_sense_pgid_start(cdev); 195 - if (ret && ret != -EBUSY) 196 - ccw_device_sense_pgid_done(cdev, ret); 197 - } 198 - return; 199 - } 200 - if (ccw_device_accumulate_and_sense(cdev, irb) != 0) 201 - return; 202 - sch = to_subchannel(cdev->dev.parent); 203 - ret = __ccw_device_check_sense_pgid(cdev); 204 - memset(&cdev->private->irb, 0, sizeof(struct irb)); 205 - switch (ret) { 206 - /* 0, -ETIME, -EOPNOTSUPP, -EAGAIN, -EACCES or -EUSERS */ 207 - case -EOPNOTSUPP: /* Sense Path Group ID not supported */ 208 - ccw_device_sense_pgid_done(cdev, -EOPNOTSUPP); 209 - break; 210 - case -ETIME: /* Sense path group id stopped by timeout. */ 211 - ccw_device_sense_pgid_done(cdev, -ETIME); 212 - break; 213 - case -EACCES: /* channel is not operational. */ 214 - sch->lpm &= ~cdev->private->imask; 215 - /* Fall through. */ 216 - case 0: /* Sense Path Group ID successful. */ 217 - cdev->private->imask >>= 1; 218 - cdev->private->iretry = 5; 219 - /* Fall through. */ 220 - case -EAGAIN: /* Try again. */ 221 - ret = __ccw_device_sense_pgid_start(cdev); 222 - if (ret != 0 && ret != -EBUSY) 223 - ccw_device_sense_pgid_done(cdev, ret); 224 - break; 225 - case -EUSERS: /* device is reserved for someone else. */ 226 - ccw_device_sense_pgid_done(cdev, -EUSERS); 227 - break; 228 - } 229 - } 230 - 231 - /* 232 - * Path Group ID helper function. 233 - */ 234 - static int 235 - __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func) 236 - { 237 - struct subchannel *sch; 238 - struct ccw1 *ccw; 239 - int ret; 240 - 241 - sch = to_subchannel(cdev->dev.parent); 242 - 243 - /* Setup sense path group id channel program. */ 244 - cdev->private->pgid[0].inf.fc = func; 245 - ccw = cdev->private->iccws; 246 - if (cdev->private->flags.pgid_single) 247 - cdev->private->pgid[0].inf.fc |= SPID_FUNC_SINGLE_PATH; 248 - else 249 - cdev->private->pgid[0].inf.fc |= SPID_FUNC_MULTI_PATH; 250 - ccw->cmd_code = CCW_CMD_SET_PGID; 251 - ccw->cda = (__u32) __pa (&cdev->private->pgid[0]); 252 - ccw->count = sizeof (struct pgid); 253 - ccw->flags = CCW_FLAG_SLI; 254 - 255 - /* Reset device status. */ 256 - memset(&cdev->private->irb, 0, sizeof(struct irb)); 257 - 258 - /* Try multiple times. */ 259 - ret = -EACCES; 260 - if (cdev->private->iretry > 0) { 261 - cdev->private->iretry--; 262 - /* Reset internal retry indication. */ 263 - cdev->private->flags.intretry = 0; 264 - ret = cio_start (sch, cdev->private->iccws, 265 - cdev->private->imask); 266 - /* We expect an interrupt in case of success or busy 267 - * indication. */ 268 - if ((ret == 0) || (ret == -EBUSY)) 269 - return ret; 270 - } 271 - /* PGID command failed on this path. */ 272 - CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel " 273 - "0.%x.%04x, lpm %02X, became 'not operational'\n", 274 - cdev->private->dev_id.devno, sch->schid.ssid, 275 - sch->schid.sch_no, cdev->private->imask); 276 - return ret; 277 - } 278 - 279 - /* 280 - * Helper function to send a nop ccw down a path. 281 - */ 282 - static int __ccw_device_do_nop(struct ccw_device *cdev) 283 - { 284 - struct subchannel *sch; 285 - struct ccw1 *ccw; 286 - int ret; 287 - 288 - sch = to_subchannel(cdev->dev.parent); 289 - 290 - /* Setup nop channel program. */ 291 - ccw = cdev->private->iccws; 292 - ccw->cmd_code = CCW_CMD_NOOP; 293 - ccw->cda = 0; 294 - ccw->count = 0; 295 - ccw->flags = CCW_FLAG_SLI; 296 - 297 - /* Reset device status. */ 298 - memset(&cdev->private->irb, 0, sizeof(struct irb)); 299 - 300 - /* Try multiple times. */ 301 - ret = -EACCES; 302 - if (cdev->private->iretry > 0) { 303 - cdev->private->iretry--; 304 - /* Reset internal retry indication. */ 305 - cdev->private->flags.intretry = 0; 306 - ret = cio_start (sch, cdev->private->iccws, 307 - cdev->private->imask); 308 - /* We expect an interrupt in case of success or busy 309 - * indication. */ 310 - if ((ret == 0) || (ret == -EBUSY)) 311 - return ret; 312 - } 313 - /* nop command failed on this path. */ 314 - CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel " 315 - "0.%x.%04x, lpm %02X, became 'not operational'\n", 316 - cdev->private->dev_id.devno, sch->schid.ssid, 317 - sch->schid.sch_no, cdev->private->imask); 318 - return ret; 319 - } 320 - 321 - 322 - /* 323 - * Called from interrupt context to check if a valid answer 324 - * to Set Path Group ID was received. 325 - */ 326 - static int 327 - __ccw_device_check_pgid(struct ccw_device *cdev) 328 - { 329 - struct subchannel *sch; 330 - struct irb *irb; 331 - 332 - sch = to_subchannel(cdev->dev.parent); 333 - irb = &cdev->private->irb; 334 - if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { 335 - /* Retry Set PGID if requested. */ 336 - if (cdev->private->flags.intretry) { 337 - cdev->private->flags.intretry = 0; 338 - return -EAGAIN; 339 - } 340 - return -ETIME; 341 - } 342 - if (irb->esw.esw0.erw.cons) { 343 - if (irb->ecw[0] & SNS0_CMD_REJECT) 344 - return -EOPNOTSUPP; 345 - /* Hmm, whatever happened, try again. */ 346 - CIO_MSG_EVENT(2, "SPID - device 0.%x.%04x, unit check, " 347 - "cnt %02d, " 348 - "sns : %02X%02X%02X%02X %02X%02X%02X%02X ...\n", 349 - cdev->private->dev_id.ssid, 350 - cdev->private->dev_id.devno, 351 - irb->esw.esw0.erw.scnt, 352 - irb->ecw[0], irb->ecw[1], 353 - irb->ecw[2], irb->ecw[3], 354 - irb->ecw[4], irb->ecw[5], 355 - irb->ecw[6], irb->ecw[7]); 356 - return -EAGAIN; 357 - } 358 - if (irb->scsw.cmd.cc == 3) { 359 - CIO_MSG_EVENT(3, "SPID - Device %04x on Subchannel 0.%x.%04x," 360 - " lpm %02X, became 'not operational'\n", 361 - cdev->private->dev_id.devno, sch->schid.ssid, 362 - sch->schid.sch_no, cdev->private->imask); 363 - return -EACCES; 364 - } 365 - return 0; 366 - } 367 - 368 - /* 369 - * Called from interrupt context to check the path status after a nop has 370 - * been send. 371 - */ 372 - static int __ccw_device_check_nop(struct ccw_device *cdev) 373 - { 374 - struct subchannel *sch; 375 - struct irb *irb; 376 - 377 - sch = to_subchannel(cdev->dev.parent); 378 - irb = &cdev->private->irb; 379 - if (irb->scsw.cmd.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) { 380 - /* Retry NOP if requested. */ 381 - if (cdev->private->flags.intretry) { 382 - cdev->private->flags.intretry = 0; 383 - return -EAGAIN; 384 - } 385 - return -ETIME; 386 - } 387 - if (irb->scsw.cmd.cc == 3) { 388 - CIO_MSG_EVENT(3, "NOP - Device %04x on Subchannel 0.%x.%04x," 389 - " lpm %02X, became 'not operational'\n", 390 - cdev->private->dev_id.devno, sch->schid.ssid, 391 - sch->schid.sch_no, cdev->private->imask); 392 - return -EACCES; 393 - } 394 - return 0; 395 - } 396 - 397 - static void 398 - __ccw_device_verify_start(struct ccw_device *cdev) 399 - { 400 - struct subchannel *sch; 401 - __u8 func; 402 - int ret; 403 - 404 - sch = to_subchannel(cdev->dev.parent); 405 - /* Repeat for all paths. */ 406 - for (; cdev->private->imask; cdev->private->imask >>= 1, 407 - cdev->private->iretry = 5) { 408 - if ((cdev->private->imask & sch->schib.pmcw.pam) == 0) 409 - /* Path not available, try next. */ 410 - continue; 411 - if (cdev->private->options.pgroup) { 412 - if (sch->opm & cdev->private->imask) 413 - func = SPID_FUNC_ESTABLISH; 414 - else 415 - func = SPID_FUNC_RESIGN; 416 - ret = __ccw_device_do_pgid(cdev, func); 417 - } else 418 - ret = __ccw_device_do_nop(cdev); 419 - /* We expect an interrupt in case of success or busy 420 - * indication. */ 421 - if (ret == 0 || ret == -EBUSY) 422 - return; 423 - /* Permanent path failure, try next. */ 424 - } 425 - /* Done with all paths. */ 426 - ccw_device_verify_done(cdev, (sch->vpm != 0) ? 0 : -ENODEV); 427 - } 428 - 429 - /* 430 - * Got interrupt for Set Path Group ID. 431 - */ 432 - void 433 - ccw_device_verify_irq(struct ccw_device *cdev, enum dev_event dev_event) 434 - { 435 - struct subchannel *sch; 436 - struct irb *irb; 437 - int ret; 438 - 439 - irb = (struct irb *) __LC_IRB; 440 - 441 - if (irb->scsw.cmd.stctl == 442 - (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { 443 - if (__ccw_device_should_retry(&irb->scsw)) 444 - __ccw_device_verify_start(cdev); 445 - return; 446 - } 447 - if (ccw_device_accumulate_and_sense(cdev, irb) != 0) 448 - return; 449 - sch = to_subchannel(cdev->dev.parent); 450 - if (cdev->private->options.pgroup) 451 - ret = __ccw_device_check_pgid(cdev); 452 - else 453 - ret = __ccw_device_check_nop(cdev); 454 - memset(&cdev->private->irb, 0, sizeof(struct irb)); 455 - 456 - switch (ret) { 457 - /* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */ 458 - case 0: 459 - /* Path verification ccw finished successfully, update lpm. */ 460 - sch->vpm |= sch->opm & cdev->private->imask; 461 - /* Go on with next path. */ 462 - cdev->private->imask >>= 1; 463 - cdev->private->iretry = 5; 464 - __ccw_device_verify_start(cdev); 465 - break; 466 - case -EOPNOTSUPP: 467 - /* 468 - * One of those strange devices which claim to be able 469 - * to do multipathing but not for Set Path Group ID. 470 - */ 471 - if (cdev->private->flags.pgid_single) 472 - cdev->private->options.pgroup = 0; 473 - else 474 - cdev->private->flags.pgid_single = 1; 475 - /* Retry */ 476 - sch->vpm = 0; 477 - cdev->private->imask = 0x80; 478 - cdev->private->iretry = 5; 479 - /* fall through. */ 480 - case -EAGAIN: /* Try again. */ 481 - __ccw_device_verify_start(cdev); 482 - break; 483 - case -ETIME: /* Set path group id stopped by timeout. */ 484 - ccw_device_verify_done(cdev, -ETIME); 485 - break; 486 - case -EACCES: /* channel is not operational. */ 487 - cdev->private->imask >>= 1; 488 - cdev->private->iretry = 5; 489 - __ccw_device_verify_start(cdev); 490 - break; 491 - } 492 - } 493 - 494 - void 495 - ccw_device_verify_start(struct ccw_device *cdev) 29 + static void verify_done(struct ccw_device *cdev, int rc) 496 30 { 497 31 struct subchannel *sch = to_subchannel(cdev->dev.parent); 32 + struct ccw_dev_id *id = &cdev->private->dev_id; 33 + int mpath = cdev->private->flags.mpath; 34 + int pgroup = cdev->private->flags.pgroup; 498 35 499 - cdev->private->flags.pgid_single = 0; 500 - cdev->private->imask = 0x80; 501 - cdev->private->iretry = 5; 502 - 503 - /* Start with empty vpm. */ 504 - sch->vpm = 0; 505 - 506 - /* Get current pam. */ 507 - if (cio_update_schib(sch)) { 508 - ccw_device_verify_done(cdev, -ENODEV); 509 - return; 36 + if (rc) 37 + goto out; 38 + /* Ensure consistent multipathing state at device and channel. */ 39 + if (sch->config.mp != mpath) { 40 + sch->config.mp = mpath; 41 + rc = cio_commit_config(sch); 510 42 } 511 - /* After 60s path verification is considered to have failed. */ 512 - ccw_device_set_timeout(cdev, 60*HZ); 513 - __ccw_device_verify_start(cdev); 514 - } 515 - 516 - static void 517 - __ccw_device_disband_start(struct ccw_device *cdev) 518 - { 519 - struct subchannel *sch; 520 - int ret; 521 - 522 - sch = to_subchannel(cdev->dev.parent); 523 - while (cdev->private->imask != 0) { 524 - if (sch->lpm & cdev->private->imask) { 525 - ret = __ccw_device_do_pgid(cdev, SPID_FUNC_DISBAND); 526 - if (ret == 0) 527 - return; 528 - } 529 - cdev->private->iretry = 5; 530 - cdev->private->imask >>= 1; 531 - } 532 - ccw_device_disband_done(cdev, (sch->lpm != 0) ? 0 : -ENODEV); 43 + out: 44 + CIO_MSG_EVENT(2, "vrfy: device 0.%x.%04x: rc=%d pgroup=%d mpath=%d " 45 + "vpm=%02x\n", id->ssid, id->devno, rc, pgroup, mpath, 46 + sch->vpm); 47 + ccw_device_verify_done(cdev, rc); 533 48 } 534 49 535 50 /* 536 - * Got interrupt for Unset Path Group ID. 51 + * Create channel program to perform a NOOP. 537 52 */ 538 - void 539 - ccw_device_disband_irq(struct ccw_device *cdev, enum dev_event dev_event) 53 + static void nop_build_cp(struct ccw_device *cdev) 540 54 { 541 - struct subchannel *sch; 542 - struct irb *irb; 543 - int ret; 55 + struct ccw_request *req = &cdev->private->req; 56 + struct ccw1 *cp = cdev->private->iccws; 544 57 545 - irb = (struct irb *) __LC_IRB; 58 + cp->cmd_code = CCW_CMD_NOOP; 59 + cp->cda = 0; 60 + cp->count = 0; 61 + cp->flags = CCW_FLAG_SLI; 62 + req->cp = cp; 63 + } 546 64 547 - if (irb->scsw.cmd.stctl == 548 - (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)) { 549 - if (__ccw_device_should_retry(&irb->scsw)) 550 - __ccw_device_disband_start(cdev); 551 - return; 552 - } 553 - if (ccw_device_accumulate_and_sense(cdev, irb) != 0) 554 - return; 555 - sch = to_subchannel(cdev->dev.parent); 556 - ret = __ccw_device_check_pgid(cdev); 557 - memset(&cdev->private->irb, 0, sizeof(struct irb)); 558 - switch (ret) { 559 - /* 0, -ETIME, -EAGAIN, -EOPNOTSUPP or -EACCES */ 560 - case 0: /* disband successful. */ 561 - ccw_device_disband_done(cdev, ret); 65 + /* 66 + * Perform NOOP on a single path. 67 + */ 68 + static void nop_do(struct ccw_device *cdev) 69 + { 70 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 71 + struct ccw_request *req = &cdev->private->req; 72 + 73 + /* Adjust lpm. */ 74 + req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam & sch->opm); 75 + if (!req->lpm) 76 + goto out_nopath; 77 + nop_build_cp(cdev); 78 + ccw_request_start(cdev); 79 + return; 80 + 81 + out_nopath: 82 + verify_done(cdev, sch->vpm ? 0 : -EACCES); 83 + } 84 + 85 + /* 86 + * Adjust NOOP I/O status. 87 + */ 88 + static enum io_status nop_filter(struct ccw_device *cdev, void *data, 89 + struct irb *irb, enum io_status status) 90 + { 91 + /* Only subchannel status might indicate a path error. */ 92 + if (status == IO_STATUS_ERROR && irb->scsw.cmd.cstat == 0) 93 + return IO_DONE; 94 + return status; 95 + } 96 + 97 + /* 98 + * Process NOOP request result for a single path. 99 + */ 100 + static void nop_callback(struct ccw_device *cdev, void *data, int rc) 101 + { 102 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 103 + struct ccw_request *req = &cdev->private->req; 104 + 105 + if (rc == 0) 106 + sch->vpm |= req->lpm; 107 + else if (rc != -EACCES) 108 + goto err; 109 + req->lpm >>= 1; 110 + nop_do(cdev); 111 + return; 112 + 113 + err: 114 + verify_done(cdev, rc); 115 + } 116 + 117 + /* 118 + * Create channel program to perform SET PGID on a single path. 119 + */ 120 + static void spid_build_cp(struct ccw_device *cdev, u8 fn) 121 + { 122 + struct ccw_request *req = &cdev->private->req; 123 + struct ccw1 *cp = cdev->private->iccws; 124 + int i = 8 - ffs(req->lpm); 125 + struct pgid *pgid = &cdev->private->pgid[i]; 126 + 127 + pgid->inf.fc = fn; 128 + cp->cmd_code = CCW_CMD_SET_PGID; 129 + cp->cda = (u32) (addr_t) pgid; 130 + cp->count = sizeof(*pgid); 131 + cp->flags = CCW_FLAG_SLI; 132 + req->cp = cp; 133 + } 134 + 135 + /* 136 + * Perform establish/resign SET PGID on a single path. 137 + */ 138 + static void spid_do(struct ccw_device *cdev) 139 + { 140 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 141 + struct ccw_request *req = &cdev->private->req; 142 + u8 fn; 143 + 144 + /* Use next available path that is not already in correct state. */ 145 + req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam & ~sch->vpm); 146 + if (!req->lpm) 147 + goto out_nopath; 148 + /* Channel program setup. */ 149 + if (req->lpm & sch->opm) 150 + fn = SPID_FUNC_ESTABLISH; 151 + else 152 + fn = SPID_FUNC_RESIGN; 153 + if (cdev->private->flags.mpath) 154 + fn |= SPID_FUNC_MULTI_PATH; 155 + spid_build_cp(cdev, fn); 156 + ccw_request_start(cdev); 157 + return; 158 + 159 + out_nopath: 160 + verify_done(cdev, sch->vpm ? 0 : -EACCES); 161 + } 162 + 163 + static void verify_start(struct ccw_device *cdev); 164 + 165 + /* 166 + * Process SET PGID request result for a single path. 167 + */ 168 + static void spid_callback(struct ccw_device *cdev, void *data, int rc) 169 + { 170 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 171 + struct ccw_request *req = &cdev->private->req; 172 + 173 + switch (rc) { 174 + case 0: 175 + sch->vpm |= req->lpm & sch->opm; 176 + break; 177 + case -EACCES: 562 178 break; 563 179 case -EOPNOTSUPP: 564 - /* 565 - * One of those strange devices which claim to be able 566 - * to do multipathing but not for Unset Path Group ID. 567 - */ 568 - cdev->private->flags.pgid_single = 1; 569 - /* fall through. */ 570 - case -EAGAIN: /* Try again. */ 571 - __ccw_device_disband_start(cdev); 180 + if (cdev->private->flags.mpath) { 181 + /* Try without multipathing. */ 182 + cdev->private->flags.mpath = 0; 183 + goto out_restart; 184 + } 185 + /* Try without pathgrouping. */ 186 + cdev->private->flags.pgroup = 0; 187 + goto out_restart; 188 + default: 189 + goto err; 190 + } 191 + req->lpm >>= 1; 192 + spid_do(cdev); 193 + return; 194 + 195 + out_restart: 196 + verify_start(cdev); 197 + return; 198 + err: 199 + verify_done(cdev, rc); 200 + } 201 + 202 + static void spid_start(struct ccw_device *cdev) 203 + { 204 + struct ccw_request *req = &cdev->private->req; 205 + 206 + /* Initialize request data. */ 207 + memset(req, 0, sizeof(*req)); 208 + req->timeout = PGID_TIMEOUT; 209 + req->maxretries = PGID_RETRIES; 210 + req->lpm = 0x80; 211 + req->callback = spid_callback; 212 + spid_do(cdev); 213 + } 214 + 215 + static int pgid_cmp(struct pgid *p1, struct pgid *p2) 216 + { 217 + return memcmp((char *) p1 + 1, (char *) p2 + 1, 218 + sizeof(struct pgid) - 1); 219 + } 220 + 221 + /* 222 + * Determine pathgroup state from PGID data. 223 + */ 224 + static void pgid_analyze(struct ccw_device *cdev, struct pgid **p, 225 + int *mismatch, int *reserved, int *reset) 226 + { 227 + struct pgid *pgid = &cdev->private->pgid[0]; 228 + struct pgid *first = NULL; 229 + int lpm; 230 + int i; 231 + 232 + *mismatch = 0; 233 + *reserved = 0; 234 + *reset = 0; 235 + for (i = 0, lpm = 0x80; i < 8; i++, pgid++, lpm >>= 1) { 236 + if ((cdev->private->pgid_valid_mask & lpm) == 0) 237 + continue; 238 + if (pgid->inf.ps.state2 == SNID_STATE2_RESVD_ELSE) 239 + *reserved = 1; 240 + if (pgid->inf.ps.state1 == SNID_STATE1_RESET) { 241 + /* A PGID was reset. */ 242 + *reset = 1; 243 + continue; 244 + } 245 + if (!first) { 246 + first = pgid; 247 + continue; 248 + } 249 + if (pgid_cmp(pgid, first) != 0) 250 + *mismatch = 1; 251 + } 252 + if (!first) 253 + first = &channel_subsystems[0]->global_pgid; 254 + *p = first; 255 + } 256 + 257 + static u8 pgid_to_vpm(struct ccw_device *cdev) 258 + { 259 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 260 + struct pgid *pgid; 261 + int i; 262 + int lpm; 263 + u8 vpm = 0; 264 + 265 + /* Set VPM bits for paths which are already in the target state. */ 266 + for (i = 0; i < 8; i++) { 267 + lpm = 0x80 >> i; 268 + if ((cdev->private->pgid_valid_mask & lpm) == 0) 269 + continue; 270 + pgid = &cdev->private->pgid[i]; 271 + if (sch->opm & lpm) { 272 + if (pgid->inf.ps.state1 != SNID_STATE1_GROUPED) 273 + continue; 274 + } else { 275 + if (pgid->inf.ps.state1 != SNID_STATE1_UNGROUPED) 276 + continue; 277 + } 278 + if (cdev->private->flags.mpath) { 279 + if (pgid->inf.ps.state3 != SNID_STATE3_MULTI_PATH) 280 + continue; 281 + } else { 282 + if (pgid->inf.ps.state3 != SNID_STATE3_SINGLE_PATH) 283 + continue; 284 + } 285 + vpm |= lpm; 286 + } 287 + 288 + return vpm; 289 + } 290 + 291 + static void pgid_fill(struct ccw_device *cdev, struct pgid *pgid) 292 + { 293 + int i; 294 + 295 + for (i = 0; i < 8; i++) 296 + memcpy(&cdev->private->pgid[i], pgid, sizeof(struct pgid)); 297 + } 298 + 299 + /* 300 + * Process SENSE PGID data and report result. 301 + */ 302 + static void snid_done(struct ccw_device *cdev, int rc) 303 + { 304 + struct ccw_dev_id *id = &cdev->private->dev_id; 305 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 306 + struct pgid *pgid; 307 + int mismatch = 0; 308 + int reserved = 0; 309 + int reset = 0; 310 + 311 + if (rc) 312 + goto out; 313 + pgid_analyze(cdev, &pgid, &mismatch, &reserved, &reset); 314 + if (reserved) 315 + rc = -EUSERS; 316 + else if (mismatch) 317 + rc = -EOPNOTSUPP; 318 + else { 319 + sch->vpm = pgid_to_vpm(cdev); 320 + pgid_fill(cdev, pgid); 321 + } 322 + out: 323 + CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x " 324 + "mism=%d rsvd=%d reset=%d\n", id->ssid, id->devno, rc, 325 + cdev->private->pgid_valid_mask, sch->vpm, mismatch, 326 + reserved, reset); 327 + switch (rc) { 328 + case 0: 329 + /* Anything left to do? */ 330 + if (sch->vpm == sch->schib.pmcw.pam) { 331 + verify_done(cdev, sch->vpm == 0 ? -EACCES : 0); 332 + return; 333 + } 334 + /* Perform path-grouping. */ 335 + spid_start(cdev); 572 336 break; 573 - case -ETIME: /* Set path group id stopped by timeout. */ 574 - ccw_device_disband_done(cdev, -ETIME); 337 + case -EOPNOTSUPP: 338 + /* Path-grouping not supported. */ 339 + cdev->private->flags.pgroup = 0; 340 + cdev->private->flags.mpath = 0; 341 + verify_start(cdev); 575 342 break; 576 - case -EACCES: /* channel is not operational. */ 577 - cdev->private->imask >>= 1; 578 - cdev->private->iretry = 5; 579 - __ccw_device_disband_start(cdev); 580 - break; 343 + default: 344 + verify_done(cdev, rc); 581 345 } 582 346 } 583 347 584 - void 585 - ccw_device_disband_start(struct ccw_device *cdev) 348 + /* 349 + * Create channel program to perform a SENSE PGID on a single path. 350 + */ 351 + static void snid_build_cp(struct ccw_device *cdev) 586 352 { 587 - /* After 60s disbanding is considered to have failed. */ 588 - ccw_device_set_timeout(cdev, 60*HZ); 353 + struct ccw_request *req = &cdev->private->req; 354 + struct ccw1 *cp = cdev->private->iccws; 355 + int i = 8 - ffs(req->lpm); 589 356 590 - cdev->private->flags.pgid_single = 0; 591 - cdev->private->iretry = 5; 592 - cdev->private->imask = 0x80; 593 - __ccw_device_disband_start(cdev); 357 + /* Channel program setup. */ 358 + cp->cmd_code = CCW_CMD_SENSE_PGID; 359 + cp->cda = (u32) (addr_t) &cdev->private->pgid[i]; 360 + cp->count = sizeof(struct pgid); 361 + cp->flags = CCW_FLAG_SLI; 362 + req->cp = cp; 594 363 } 364 + 365 + /* 366 + * Perform SENSE PGID on a single path. 367 + */ 368 + static void snid_do(struct ccw_device *cdev) 369 + { 370 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 371 + struct ccw_request *req = &cdev->private->req; 372 + 373 + /* Adjust lpm if paths are not set in pam. */ 374 + req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam); 375 + if (!req->lpm) 376 + goto out_nopath; 377 + snid_build_cp(cdev); 378 + ccw_request_start(cdev); 379 + return; 380 + 381 + out_nopath: 382 + snid_done(cdev, cdev->private->pgid_valid_mask ? 0 : -EACCES); 383 + } 384 + 385 + /* 386 + * Process SENSE PGID request result for single path. 387 + */ 388 + static void snid_callback(struct ccw_device *cdev, void *data, int rc) 389 + { 390 + struct ccw_request *req = &cdev->private->req; 391 + 392 + if (rc == 0) 393 + cdev->private->pgid_valid_mask |= req->lpm; 394 + else if (rc != -EACCES) 395 + goto err; 396 + req->lpm >>= 1; 397 + snid_do(cdev); 398 + return; 399 + 400 + err: 401 + snid_done(cdev, rc); 402 + } 403 + 404 + /* 405 + * Perform path verification. 406 + */ 407 + static void verify_start(struct ccw_device *cdev) 408 + { 409 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 410 + struct ccw_request *req = &cdev->private->req; 411 + struct ccw_dev_id *devid = &cdev->private->dev_id; 412 + 413 + sch->vpm = 0; 414 + /* Initialize request data. */ 415 + memset(req, 0, sizeof(*req)); 416 + req->timeout = PGID_TIMEOUT; 417 + req->maxretries = PGID_RETRIES; 418 + req->lpm = 0x80; 419 + if (cdev->private->flags.pgroup) { 420 + CIO_TRACE_EVENT(4, "snid"); 421 + CIO_HEX_EVENT(4, devid, sizeof(*devid)); 422 + req->callback = snid_callback; 423 + snid_do(cdev); 424 + } else { 425 + CIO_TRACE_EVENT(4, "nop"); 426 + CIO_HEX_EVENT(4, devid, sizeof(*devid)); 427 + req->filter = nop_filter; 428 + req->callback = nop_callback; 429 + nop_do(cdev); 430 + } 431 + } 432 + 433 + /** 434 + * ccw_device_verify_start - perform path verification 435 + * @cdev: ccw device 436 + * 437 + * Perform an I/O on each available channel path to @cdev to determine which 438 + * paths are operational. The resulting path mask is stored in sch->vpm. 439 + * If device options specify pathgrouping, establish a pathgroup for the 440 + * operational paths. When finished, call ccw_device_verify_done with a 441 + * return code specifying the result. 442 + */ 443 + void ccw_device_verify_start(struct ccw_device *cdev) 444 + { 445 + CIO_TRACE_EVENT(4, "vrfy"); 446 + CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); 447 + /* Initialize PGID data. */ 448 + memset(cdev->private->pgid, 0, sizeof(cdev->private->pgid)); 449 + cdev->private->pgid_valid_mask = 0; 450 + /* 451 + * Initialize pathgroup and multipath state with target values. 452 + * They may change in the course of path verification. 453 + */ 454 + cdev->private->flags.pgroup = cdev->private->options.pgroup; 455 + cdev->private->flags.mpath = cdev->private->options.mpath; 456 + cdev->private->flags.doverify = 0; 457 + verify_start(cdev); 458 + } 459 + 460 + /* 461 + * Process disband SET PGID request result. 462 + */ 463 + static void disband_callback(struct ccw_device *cdev, void *data, int rc) 464 + { 465 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 466 + struct ccw_dev_id *id = &cdev->private->dev_id; 467 + 468 + if (rc) 469 + goto out; 470 + /* Ensure consistent multipathing state at device and channel. */ 471 + cdev->private->flags.mpath = 0; 472 + if (sch->config.mp) { 473 + sch->config.mp = 0; 474 + rc = cio_commit_config(sch); 475 + } 476 + out: 477 + CIO_MSG_EVENT(0, "disb: device 0.%x.%04x: rc=%d\n", id->ssid, id->devno, 478 + rc); 479 + ccw_device_disband_done(cdev, rc); 480 + } 481 + 482 + /** 483 + * ccw_device_disband_start - disband pathgroup 484 + * @cdev: ccw device 485 + * 486 + * Execute a SET PGID channel program on @cdev to disband a previously 487 + * established pathgroup. When finished, call ccw_device_disband_done with 488 + * a return code specifying the result. 489 + */ 490 + void ccw_device_disband_start(struct ccw_device *cdev) 491 + { 492 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 493 + struct ccw_request *req = &cdev->private->req; 494 + u8 fn; 495 + 496 + CIO_TRACE_EVENT(4, "disb"); 497 + CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); 498 + /* Request setup. */ 499 + memset(req, 0, sizeof(*req)); 500 + req->timeout = PGID_TIMEOUT; 501 + req->maxretries = PGID_RETRIES; 502 + req->lpm = sch->schib.pmcw.pam & sch->opm; 503 + req->callback = disband_callback; 504 + fn = SPID_FUNC_DISBAND; 505 + if (cdev->private->flags.mpath) 506 + fn |= SPID_FUNC_MULTI_PATH; 507 + spid_build_cp(cdev, fn); 508 + ccw_request_start(cdev); 509 + } 510 + 511 + static void stlck_build_cp(struct ccw_device *cdev, void *buf1, void *buf2) 512 + { 513 + struct ccw_request *req = &cdev->private->req; 514 + struct ccw1 *cp = cdev->private->iccws; 515 + 516 + cp[0].cmd_code = CCW_CMD_STLCK; 517 + cp[0].cda = (u32) (addr_t) buf1; 518 + cp[0].count = 32; 519 + cp[0].flags = CCW_FLAG_CC; 520 + cp[1].cmd_code = CCW_CMD_RELEASE; 521 + cp[1].cda = (u32) (addr_t) buf2; 522 + cp[1].count = 32; 523 + cp[1].flags = 0; 524 + req->cp = cp; 525 + } 526 + 527 + static void stlck_callback(struct ccw_device *cdev, void *data, int rc) 528 + { 529 + ccw_device_stlck_done(cdev, data, rc); 530 + } 531 + 532 + /** 533 + * ccw_device_stlck_start - perform unconditional release 534 + * @cdev: ccw device 535 + * @data: data pointer to be passed to ccw_device_stlck_done 536 + * @buf1: data pointer used in channel program 537 + * @buf2: data pointer used in channel program 538 + * 539 + * Execute a channel program on @cdev to release an existing PGID reservation. 540 + * When finished, call ccw_device_stlck_done with a return code specifying the 541 + * result. 542 + */ 543 + void ccw_device_stlck_start(struct ccw_device *cdev, void *data, void *buf1, 544 + void *buf2) 545 + { 546 + struct subchannel *sch = to_subchannel(cdev->dev.parent); 547 + struct ccw_request *req = &cdev->private->req; 548 + 549 + CIO_TRACE_EVENT(4, "stlck"); 550 + CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); 551 + /* Request setup. */ 552 + memset(req, 0, sizeof(*req)); 553 + req->timeout = PGID_TIMEOUT; 554 + req->maxretries = PGID_RETRIES; 555 + req->lpm = sch->schib.pmcw.pam & sch->opm; 556 + req->data = data; 557 + req->callback = stlck_callback; 558 + stlck_build_cp(cdev, buf1, buf2); 559 + ccw_request_start(cdev); 560 + } 561 +
-3
drivers/s390/cio/device_status.c
··· 336 336 sense_ccw->count = SENSE_MAX_COUNT; 337 337 sense_ccw->flags = CCW_FLAG_SLI; 338 338 339 - /* Reset internal retry indication. */ 340 - cdev->private->flags.intretry = 0; 341 - 342 339 rc = cio_start(sch, sense_ccw, 0xff); 343 340 if (rc == -ENODEV || rc == -EACCES) 344 341 dev_fsm_event(cdev, DEV_EVENT_VERIFY);
+67 -6
drivers/s390/cio/io_sch.h
··· 1 1 #ifndef S390_IO_SCH_H 2 2 #define S390_IO_SCH_H 3 3 4 + #include <linux/types.h> 4 5 #include <asm/schid.h> 6 + #include <asm/ccwdev.h> 7 + #include "css.h" 5 8 6 9 /* 7 10 * command-mode operation request block ··· 71 68 #define MAX_CIWS 8 72 69 73 70 /* 71 + * Possible status values for a CCW request's I/O. 72 + */ 73 + enum io_status { 74 + IO_DONE, 75 + IO_RUNNING, 76 + IO_STATUS_ERROR, 77 + IO_PATH_ERROR, 78 + IO_REJECTED, 79 + IO_KILLED 80 + }; 81 + 82 + /** 83 + * ccw_request - Internal CCW request. 84 + * @cp: channel program to start 85 + * @timeout: maximum allowable time in jiffies between start I/O and interrupt 86 + * @maxretries: number of retries per I/O operation and path 87 + * @lpm: mask of paths to use 88 + * @check: optional callback that determines if results are final 89 + * @filter: optional callback to adjust request status based on IRB data 90 + * @callback: final callback 91 + * @data: user-defined pointer passed to all callbacks 92 + * @mask: current path mask 93 + * @retries: current number of retries 94 + * @drc: delayed return code 95 + * @cancel: non-zero if request was cancelled 96 + * @done: non-zero if request was finished 97 + */ 98 + struct ccw_request { 99 + struct ccw1 *cp; 100 + unsigned long timeout; 101 + u16 maxretries; 102 + u8 lpm; 103 + int (*check)(struct ccw_device *, void *); 104 + enum io_status (*filter)(struct ccw_device *, void *, struct irb *, 105 + enum io_status); 106 + void (*callback)(struct ccw_device *, void *, int); 107 + void *data; 108 + /* These fields are used internally. */ 109 + u16 mask; 110 + u16 retries; 111 + int drc; 112 + int cancel:1; 113 + int done:1; 114 + } __attribute__((packed)); 115 + 116 + /* 74 117 * sense-id response buffer layout 75 118 */ 76 119 struct senseid { ··· 131 82 struct ciw ciw[MAX_CIWS]; /* variable # of CIWs */ 132 83 } __attribute__ ((packed, aligned(4))); 133 84 85 + enum cdev_todo { 86 + CDEV_TODO_NOTHING, 87 + CDEV_TODO_ENABLE_CMF, 88 + CDEV_TODO_REBIND, 89 + CDEV_TODO_REGISTER, 90 + CDEV_TODO_UNREG, 91 + CDEV_TODO_UNREG_EVAL, 92 + }; 93 + 134 94 struct ccw_device_private { 135 95 struct ccw_device *cdev; 136 96 struct subchannel *sch; 137 97 int state; /* device state */ 138 98 atomic_t onoff; 139 - unsigned long registered; 140 99 struct ccw_dev_id dev_id; /* device id */ 141 100 struct subchannel_id schid; /* subchannel number */ 142 - u8 imask; /* lpm mask for SNID/SID/SPGID */ 143 - int iretry; /* retry counter SNID/SID/SPGID */ 101 + struct ccw_request req; /* internal I/O request */ 102 + int iretry; 103 + u8 pgid_valid_mask; /* mask of valid PGIDs */ 144 104 struct { 145 105 unsigned int fast:1; /* post with "channel end" */ 146 106 unsigned int repall:1; /* report every interrupt status */ 147 107 unsigned int pgroup:1; /* do path grouping */ 148 108 unsigned int force:1; /* allow forced online */ 109 + unsigned int mpath:1; /* do multipathing */ 149 110 } __attribute__ ((packed)) options; 150 111 struct { 151 - unsigned int pgid_single:1; /* use single path for Set PGID */ 152 112 unsigned int esid:1; /* Ext. SenseID supported by HW */ 153 113 unsigned int dosense:1; /* delayed SENSE required */ 154 114 unsigned int doverify:1; /* delayed path verification */ 155 115 unsigned int donotify:1; /* call notify function */ 156 116 unsigned int recog_done:1; /* dev. recog. complete */ 157 117 unsigned int fake_irb:1; /* deliver faked irb */ 158 - unsigned int intretry:1; /* retry internal operation */ 159 118 unsigned int resuming:1; /* recognition while resume */ 119 + unsigned int pgroup:1; /* pathgroup is set up */ 120 + unsigned int mpath:1; /* multipathing is set up */ 121 + unsigned int initialized:1; /* set if initial reference held */ 160 122 } __attribute__((packed)) flags; 161 123 unsigned long intparm; /* user interruption parameter */ 162 124 struct qdio_irq *qdio_data; ··· 175 115 struct senseid senseid; /* SenseID info */ 176 116 struct pgid pgid[8]; /* path group IDs per chpid*/ 177 117 struct ccw1 iccws[2]; /* ccws for SNID/SID/SPGID commands */ 178 - struct work_struct kick_work; 118 + struct work_struct todo_work; 119 + enum cdev_todo todo; 179 120 wait_queue_head_t wait_q; 180 121 struct timer_list timer; 181 122 void *cmb; /* measurement information */
+23 -8
drivers/s390/crypto/ap_bus.c
··· 102 102 static DECLARE_WAIT_QUEUE_HEAD(ap_poll_wait); 103 103 static struct task_struct *ap_poll_kthread = NULL; 104 104 static DEFINE_MUTEX(ap_poll_thread_mutex); 105 + static DEFINE_SPINLOCK(ap_poll_timer_lock); 105 106 static void *ap_interrupt_indicator; 106 107 static struct hrtimer ap_poll_timer; 107 108 /* In LPAR poll with 4kHz frequency. Poll every 250000 nanoseconds. ··· 283 282 * @psmid: The program supplied message identifier 284 283 * @msg: The message text 285 284 * @length: The message length 285 + * @special: Special Bit 286 286 * 287 287 * Returns AP queue status structure. 288 288 * Condition code 1 on NQAP can't happen because the L bit is 1. ··· 291 289 * because a segment boundary was reached. The NQAP is repeated. 292 290 */ 293 291 static inline struct ap_queue_status 294 - __ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length) 292 + __ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length, 293 + unsigned int special) 295 294 { 296 295 typedef struct { char _[length]; } msgblock; 297 296 register unsigned long reg0 asm ("0") = qid | 0x40000000UL; ··· 301 298 register unsigned long reg3 asm ("3") = (unsigned long) length; 302 299 register unsigned long reg4 asm ("4") = (unsigned int) (psmid >> 32); 303 300 register unsigned long reg5 asm ("5") = (unsigned int) psmid; 301 + 302 + if (special == 1) 303 + reg0 |= 0x400000UL; 304 304 305 305 asm volatile ( 306 306 "0: .long 0xb2ad0042\n" /* DQAP */ ··· 318 312 { 319 313 struct ap_queue_status status; 320 314 321 - status = __ap_send(qid, psmid, msg, length); 315 + status = __ap_send(qid, psmid, msg, length, 0); 322 316 switch (status.response_code) { 323 317 case AP_RESPONSE_NORMAL: 324 318 return 0; 325 319 case AP_RESPONSE_Q_FULL: 326 320 case AP_RESPONSE_RESET_IN_PROGRESS: 327 321 return -EBUSY; 322 + case AP_RESPONSE_REQ_FAC_NOT_INST: 323 + return -EINVAL; 328 324 default: /* Device is gone. */ 329 325 return -ENODEV; 330 326 } ··· 1016 1008 } 1017 1009 1018 1010 status = __ap_send(ap_dev->qid, 0x0102030405060708ULL, 1019 - msg, sizeof(msg)); 1011 + msg, sizeof(msg), 0); 1020 1012 if (status.response_code != AP_RESPONSE_NORMAL) { 1021 1013 rc = -ENODEV; 1022 1014 goto out_free; ··· 1171 1163 static inline void ap_schedule_poll_timer(void) 1172 1164 { 1173 1165 ktime_t hr_time; 1166 + 1167 + spin_lock_bh(&ap_poll_timer_lock); 1174 1168 if (ap_using_interrupts() || ap_suspend_flag) 1175 - return; 1169 + goto out; 1176 1170 if (hrtimer_is_queued(&ap_poll_timer)) 1177 - return; 1171 + goto out; 1178 1172 if (ktime_to_ns(hrtimer_expires_remaining(&ap_poll_timer)) <= 0) { 1179 1173 hr_time = ktime_set(0, poll_timeout); 1180 1174 hrtimer_forward_now(&ap_poll_timer, hr_time); 1181 1175 hrtimer_restart(&ap_poll_timer); 1182 1176 } 1183 - return; 1177 + out: 1178 + spin_unlock_bh(&ap_poll_timer_lock); 1184 1179 } 1185 1180 1186 1181 /** ··· 1254 1243 /* Start the next request on the queue. */ 1255 1244 ap_msg = list_entry(ap_dev->requestq.next, struct ap_message, list); 1256 1245 status = __ap_send(ap_dev->qid, ap_msg->psmid, 1257 - ap_msg->message, ap_msg->length); 1246 + ap_msg->message, ap_msg->length, ap_msg->special); 1258 1247 switch (status.response_code) { 1259 1248 case AP_RESPONSE_NORMAL: 1260 1249 atomic_inc(&ap_poll_requests); ··· 1272 1261 *flags |= 2; 1273 1262 break; 1274 1263 case AP_RESPONSE_MESSAGE_TOO_BIG: 1264 + case AP_RESPONSE_REQ_FAC_NOT_INST: 1275 1265 return -EINVAL; 1276 1266 default: 1277 1267 return -ENODEV; ··· 1314 1302 if (list_empty(&ap_dev->requestq) && 1315 1303 ap_dev->queue_count < ap_dev->queue_depth) { 1316 1304 status = __ap_send(ap_dev->qid, ap_msg->psmid, 1317 - ap_msg->message, ap_msg->length); 1305 + ap_msg->message, ap_msg->length, 1306 + ap_msg->special); 1318 1307 switch (status.response_code) { 1319 1308 case AP_RESPONSE_NORMAL: 1320 1309 list_add_tail(&ap_msg->list, &ap_dev->pendingq); ··· 1330 1317 ap_dev->requestq_count++; 1331 1318 ap_dev->total_request_count++; 1332 1319 return -EBUSY; 1320 + case AP_RESPONSE_REQ_FAC_NOT_INST: 1333 1321 case AP_RESPONSE_MESSAGE_TOO_BIG: 1334 1322 ap_dev->drv->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL)); 1335 1323 return -EINVAL; ··· 1672 1658 */ 1673 1659 if (MACHINE_IS_VM) 1674 1660 poll_timeout = 1500000; 1661 + spin_lock_init(&ap_poll_timer_lock); 1675 1662 hrtimer_init(&ap_poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS); 1676 1663 ap_poll_timer.function = ap_poll_timeout; 1677 1664
+16 -2
drivers/s390/crypto/ap_bus.h
··· 87 87 #define AP_RESPONSE_INDEX_TOO_BIG 0x11 88 88 #define AP_RESPONSE_NO_FIRST_PART 0x13 89 89 #define AP_RESPONSE_MESSAGE_TOO_BIG 0x15 90 + #define AP_RESPONSE_REQ_FAC_NOT_INST 0x16 90 91 91 92 /* 92 93 * Known device types ··· 97 96 #define AP_DEVICE_TYPE_PCIXCC 5 98 97 #define AP_DEVICE_TYPE_CEX2A 6 99 98 #define AP_DEVICE_TYPE_CEX2C 7 100 - #define AP_DEVICE_TYPE_CEX2A2 8 101 - #define AP_DEVICE_TYPE_CEX2C2 9 99 + #define AP_DEVICE_TYPE_CEX3A 8 100 + #define AP_DEVICE_TYPE_CEX3C 9 102 101 103 102 /* 104 103 * AP reset flag states ··· 162 161 size_t length; /* Message length. */ 163 162 164 163 void *private; /* ap driver private pointer. */ 164 + unsigned int special:1; /* Used for special commands. */ 165 165 }; 166 166 167 167 #define AP_DEVICE(dt) \ 168 168 .dev_type=(dt), \ 169 169 .match_flags=AP_DEVICE_ID_MATCH_DEVICE_TYPE, 170 + 171 + /** 172 + * ap_init_message() - Initialize ap_message. 173 + * Initialize a message before using. Otherwise this might result in 174 + * unexpected behaviour. 175 + */ 176 + static inline void ap_init_message(struct ap_message *ap_msg) 177 + { 178 + ap_msg->psmid = 0; 179 + ap_msg->length = 0; 180 + ap_msg->special = 0; 181 + } 170 182 171 183 /* 172 184 * Note: don't use ap_send/ap_recv after using ap_queue_message
+7 -4
drivers/s390/crypto/zcrypt_api.c
··· 299 299 */ 300 300 static int zcrypt_open(struct inode *inode, struct file *filp) 301 301 { 302 - lock_kernel(); 303 302 atomic_inc(&zcrypt_open_count); 304 - unlock_kernel(); 305 303 return 0; 306 304 } 307 305 ··· 1007 1009 zcrypt_count_type(ZCRYPT_CEX2C)); 1008 1010 len += sprintf(resp_buff + len, "CEX2A count: %d\n", 1009 1011 zcrypt_count_type(ZCRYPT_CEX2A)); 1012 + len += sprintf(resp_buff + len, "CEX3C count: %d\n", 1013 + zcrypt_count_type(ZCRYPT_CEX3C)); 1014 + len += sprintf(resp_buff + len, "CEX3A count: %d\n", 1015 + zcrypt_count_type(ZCRYPT_CEX3A)); 1010 1016 len += sprintf(resp_buff + len, "requestq count: %d\n", 1011 1017 zcrypt_requestq_count()); 1012 1018 len += sprintf(resp_buff + len, "pendingq count: %d\n", ··· 1019 1017 atomic_read(&zcrypt_open_count)); 1020 1018 zcrypt_status_mask(workarea); 1021 1019 len += sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) " 1022 - "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A", 1020 + "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A 7=CEX3C 8=CEX3A", 1023 1021 resp_buff+len, workarea, AP_DEVICES); 1024 1022 zcrypt_qdepth_mask(workarea); 1025 1023 len += sprinthx("Waiting work element counts", ··· 1097 1095 * '0' for no device, '1' for PCICA, '2' for PCICC, 1098 1096 * '3' for PCIXCC_MCL2, '4' for PCIXCC_MCL3, 1099 1097 * '5' for CEX2C and '6' for CEX2A' 1098 + * '7' for CEX3C and '8' for CEX3A 1100 1099 */ 1101 - if (*ptr >= '0' && *ptr <= '6') 1100 + if (*ptr >= '0' && *ptr <= '8') 1102 1101 j++; 1103 1102 else if (*ptr == 'd' || *ptr == 'D') 1104 1103 zcrypt_disable_card(j++);
+2
drivers/s390/crypto/zcrypt_api.h
··· 71 71 #define ZCRYPT_PCIXCC_MCL3 4 72 72 #define ZCRYPT_CEX2C 5 73 73 #define ZCRYPT_CEX2A 6 74 + #define ZCRYPT_CEX3C 7 75 + #define ZCRYPT_CEX3A 8 74 76 75 77 /** 76 78 * Large random numbers are pulled in 4096 byte chunks from the crypto cards
+48 -25
drivers/s390/crypto/zcrypt_cex2a.c
··· 39 39 40 40 #define CEX2A_MIN_MOD_SIZE 1 /* 8 bits */ 41 41 #define CEX2A_MAX_MOD_SIZE 256 /* 2048 bits */ 42 + #define CEX3A_MIN_MOD_SIZE CEX2A_MIN_MOD_SIZE 43 + #define CEX3A_MAX_MOD_SIZE CEX2A_MAX_MOD_SIZE 42 44 43 45 #define CEX2A_SPEED_RATING 970 46 + #define CEX3A_SPEED_RATING 900 /* Fixme: Needs finetuning */ 44 47 45 48 #define CEX2A_MAX_MESSAGE_SIZE 0x390 /* sizeof(struct type50_crb2_msg) */ 46 49 #define CEX2A_MAX_RESPONSE_SIZE 0x110 /* max outputdatalength + type80_hdr */ 47 50 51 + #define CEX3A_MAX_MESSAGE_SIZE CEX2A_MAX_MESSAGE_SIZE 52 + #define CEX3A_MAX_RESPONSE_SIZE CEX2A_MAX_RESPONSE_SIZE 53 + 48 54 #define CEX2A_CLEANUP_TIME (15*HZ) 55 + #define CEX3A_CLEANUP_TIME CEX2A_CLEANUP_TIME 49 56 50 57 static struct ap_device_id zcrypt_cex2a_ids[] = { 51 58 { AP_DEVICE(AP_DEVICE_TYPE_CEX2A) }, 52 - { AP_DEVICE(AP_DEVICE_TYPE_CEX2A2) }, 59 + { AP_DEVICE(AP_DEVICE_TYPE_CEX3A) }, 53 60 { /* end of list */ }, 54 61 }; 55 62 ··· 305 298 struct completion work; 306 299 int rc; 307 300 301 + ap_init_message(&ap_msg); 308 302 ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL); 309 303 if (!ap_msg.message) 310 304 return -ENOMEM; ··· 343 335 struct completion work; 344 336 int rc; 345 337 338 + ap_init_message(&ap_msg); 346 339 ap_msg.message = kmalloc(CEX2A_MAX_MESSAGE_SIZE, GFP_KERNEL); 347 340 if (!ap_msg.message) 348 341 return -ENOMEM; ··· 382 373 */ 383 374 static int zcrypt_cex2a_probe(struct ap_device *ap_dev) 384 375 { 385 - struct zcrypt_device *zdev; 386 - int rc; 376 + struct zcrypt_device *zdev = NULL; 377 + int rc = 0; 387 378 388 - zdev = zcrypt_device_alloc(CEX2A_MAX_RESPONSE_SIZE); 389 - if (!zdev) 390 - return -ENOMEM; 391 - zdev->ap_dev = ap_dev; 392 - zdev->ops = &zcrypt_cex2a_ops; 393 - zdev->online = 1; 394 - zdev->user_space_type = ZCRYPT_CEX2A; 395 - zdev->type_string = "CEX2A"; 396 - zdev->min_mod_size = CEX2A_MIN_MOD_SIZE; 397 - zdev->max_mod_size = CEX2A_MAX_MOD_SIZE; 398 - zdev->short_crt = 1; 399 - zdev->speed_rating = CEX2A_SPEED_RATING; 400 - ap_dev->reply = &zdev->reply; 401 - ap_dev->private = zdev; 402 - rc = zcrypt_device_register(zdev); 403 - if (rc) 404 - goto out_free; 405 - return 0; 406 - 407 - out_free: 408 - ap_dev->private = NULL; 409 - zcrypt_device_free(zdev); 379 + switch (ap_dev->device_type) { 380 + case AP_DEVICE_TYPE_CEX2A: 381 + zdev = zcrypt_device_alloc(CEX2A_MAX_RESPONSE_SIZE); 382 + if (!zdev) 383 + return -ENOMEM; 384 + zdev->user_space_type = ZCRYPT_CEX2A; 385 + zdev->type_string = "CEX2A"; 386 + zdev->min_mod_size = CEX2A_MIN_MOD_SIZE; 387 + zdev->max_mod_size = CEX2A_MAX_MOD_SIZE; 388 + zdev->short_crt = 1; 389 + zdev->speed_rating = CEX2A_SPEED_RATING; 390 + break; 391 + case AP_DEVICE_TYPE_CEX3A: 392 + zdev = zcrypt_device_alloc(CEX3A_MAX_RESPONSE_SIZE); 393 + if (!zdev) 394 + return -ENOMEM; 395 + zdev->user_space_type = ZCRYPT_CEX3A; 396 + zdev->type_string = "CEX3A"; 397 + zdev->min_mod_size = CEX3A_MIN_MOD_SIZE; 398 + zdev->max_mod_size = CEX3A_MAX_MOD_SIZE; 399 + zdev->short_crt = 1; 400 + zdev->speed_rating = CEX3A_SPEED_RATING; 401 + break; 402 + } 403 + if (zdev != NULL) { 404 + zdev->ap_dev = ap_dev; 405 + zdev->ops = &zcrypt_cex2a_ops; 406 + zdev->online = 1; 407 + ap_dev->reply = &zdev->reply; 408 + ap_dev->private = zdev; 409 + rc = zcrypt_device_register(zdev); 410 + } 411 + if (rc) { 412 + ap_dev->private = NULL; 413 + zcrypt_device_free(zdev); 414 + } 410 415 return rc; 411 416 } 412 417
+2
drivers/s390/crypto/zcrypt_pcica.c
··· 281 281 struct completion work; 282 282 int rc; 283 283 284 + ap_init_message(&ap_msg); 284 285 ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); 285 286 if (!ap_msg.message) 286 287 return -ENOMEM; ··· 319 318 struct completion work; 320 319 int rc; 321 320 321 + ap_init_message(&ap_msg); 322 322 ap_msg.message = kmalloc(PCICA_MAX_MESSAGE_SIZE, GFP_KERNEL); 323 323 if (!ap_msg.message) 324 324 return -ENOMEM;
+2
drivers/s390/crypto/zcrypt_pcicc.c
··· 483 483 struct completion work; 484 484 int rc; 485 485 486 + ap_init_message(&ap_msg); 486 487 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 487 488 if (!ap_msg.message) 488 489 return -ENOMEM; ··· 522 521 struct completion work; 523 522 int rc; 524 523 524 + ap_init_message(&ap_msg); 525 525 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 526 526 if (!ap_msg.message) 527 527 return -ENOMEM;
+32 -6
drivers/s390/crypto/zcrypt_pcixcc.c
··· 43 43 #define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */ 44 44 #define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */ 45 45 #define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */ 46 + #define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE 47 + #define CEX3C_MAX_MOD_SIZE PCIXCC_MAX_MOD_SIZE 46 48 47 - #define PCIXCC_MCL2_SPEED_RATING 7870 /* FIXME: needs finetuning */ 49 + #define PCIXCC_MCL2_SPEED_RATING 7870 48 50 #define PCIXCC_MCL3_SPEED_RATING 7870 49 - #define CEX2C_SPEED_RATING 8540 51 + #define CEX2C_SPEED_RATING 7000 52 + #define CEX3C_SPEED_RATING 6500 /* FIXME: needs finetuning */ 50 53 51 54 #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */ 52 55 #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */ ··· 75 72 static struct ap_device_id zcrypt_pcixcc_ids[] = { 76 73 { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) }, 77 74 { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) }, 78 - { AP_DEVICE(AP_DEVICE_TYPE_CEX2C2) }, 75 + { AP_DEVICE(AP_DEVICE_TYPE_CEX3C) }, 79 76 { /* end of list */ }, 80 77 }; 81 78 ··· 328 325 return -EFAULT; 329 326 function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; 330 327 memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code)); 328 + 329 + if (memcmp(function_code, "US", 2) == 0) 330 + ap_msg->special = 1; 331 + else 332 + ap_msg->special = 0; 331 333 332 334 /* copy data block */ 333 335 if (xcRB->request_data_length && ··· 696 688 }; 697 689 int rc; 698 690 691 + ap_init_message(&ap_msg); 699 692 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 700 693 if (!ap_msg.message) 701 694 return -ENOMEM; ··· 736 727 }; 737 728 int rc; 738 729 730 + ap_init_message(&ap_msg); 739 731 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 740 732 if (!ap_msg.message) 741 733 return -ENOMEM; ··· 776 766 }; 777 767 int rc; 778 768 769 + ap_init_message(&ap_msg); 779 770 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); 780 771 if (!ap_msg.message) 781 772 return -ENOMEM; ··· 816 805 }; 817 806 int rc; 818 807 808 + ap_init_message(&ap_msg); 819 809 ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); 820 810 if (!ap_msg.message) 821 811 return -ENOMEM; ··· 984 972 } __attribute__((packed)) *reply; 985 973 int rc, i; 986 974 975 + ap_init_message(&ap_msg); 987 976 ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); 988 977 if (!ap_msg.message) 989 978 return -ENOMEM; ··· 1029 1016 static int zcrypt_pcixcc_probe(struct ap_device *ap_dev) 1030 1017 { 1031 1018 struct zcrypt_device *zdev; 1032 - int rc; 1019 + int rc = 0; 1033 1020 1034 1021 zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE); 1035 1022 if (!zdev) 1036 1023 return -ENOMEM; 1037 1024 zdev->ap_dev = ap_dev; 1038 1025 zdev->online = 1; 1039 - if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) { 1026 + switch (ap_dev->device_type) { 1027 + case AP_DEVICE_TYPE_PCIXCC: 1040 1028 rc = zcrypt_pcixcc_mcl(ap_dev); 1041 1029 if (rc < 0) { 1042 1030 zcrypt_device_free(zdev); ··· 1055 1041 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; 1056 1042 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; 1057 1043 } 1058 - } else { 1044 + break; 1045 + case AP_DEVICE_TYPE_CEX2C: 1059 1046 zdev->user_space_type = ZCRYPT_CEX2C; 1060 1047 zdev->type_string = "CEX2C"; 1061 1048 zdev->speed_rating = CEX2C_SPEED_RATING; 1062 1049 zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; 1063 1050 zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; 1051 + break; 1052 + case AP_DEVICE_TYPE_CEX3C: 1053 + zdev->user_space_type = ZCRYPT_CEX3C; 1054 + zdev->type_string = "CEX3C"; 1055 + zdev->speed_rating = CEX3C_SPEED_RATING; 1056 + zdev->min_mod_size = CEX3C_MIN_MOD_SIZE; 1057 + zdev->max_mod_size = CEX3C_MAX_MOD_SIZE; 1058 + break; 1059 + default: 1060 + goto out_free; 1064 1061 } 1062 + 1065 1063 rc = zcrypt_pcixcc_rng_supported(ap_dev); 1066 1064 if (rc < 0) { 1067 1065 zcrypt_device_free(zdev);