diff options
31 files changed, 459 insertions, 348 deletions
diff --git a/arch/s390/crypto/crypt_s390.h b/arch/s390/crypto/crypt_s390.h index 2775d2618332..95f5160df27f 100644 --- a/arch/s390/crypto/crypt_s390.h +++ b/arch/s390/crypto/crypt_s390.h | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | #define CRYPT_S390_PRIORITY 300 | 24 | #define CRYPT_S390_PRIORITY 300 |
| 25 | #define CRYPT_S390_COMPOSITE_PRIORITY 400 | 25 | #define CRYPT_S390_COMPOSITE_PRIORITY 400 |
| 26 | 26 | ||
| 27 | /* s930 cryptographic operations */ | 27 | /* s390 cryptographic operations */ |
| 28 | enum crypt_s390_operations { | 28 | enum crypt_s390_operations { |
| 29 | CRYPT_S390_KM = 0x0100, | 29 | CRYPT_S390_KM = 0x0100, |
| 30 | CRYPT_S390_KMC = 0x0200, | 30 | CRYPT_S390_KMC = 0x0200, |
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 50538e545618..e6289ee74ecd 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
| @@ -171,37 +171,6 @@ static inline int memory_fast_detect(void) | |||
| 171 | } | 171 | } |
| 172 | #endif | 172 | #endif |
| 173 | 173 | ||
| 174 | #define ADDR2G (1UL << 31) | ||
| 175 | |||
| 176 | static noinline __init unsigned long sclp_memory_detect(void) | ||
| 177 | { | ||
| 178 | struct sclp_readinfo_sccb *sccb; | ||
| 179 | unsigned long long memsize; | ||
| 180 | |||
| 181 | sccb = &s390_readinfo_sccb; | ||
| 182 | |||
| 183 | if (sccb->header.response_code != 0x10) | ||
| 184 | return 0; | ||
| 185 | |||
| 186 | if (sccb->rnsize) | ||
| 187 | memsize = sccb->rnsize << 20; | ||
| 188 | else | ||
| 189 | memsize = sccb->rnsize2 << 20; | ||
| 190 | if (sccb->rnmax) | ||
| 191 | memsize *= sccb->rnmax; | ||
| 192 | else | ||
| 193 | memsize *= sccb->rnmax2; | ||
| 194 | #ifndef CONFIG_64BIT | ||
| 195 | /* | ||
| 196 | * Can't deal with more than 2G in 31 bit addressing mode, so | ||
| 197 | * limit the value in order to avoid strange side effects. | ||
| 198 | */ | ||
| 199 | if (memsize > ADDR2G) | ||
| 200 | memsize = ADDR2G; | ||
| 201 | #endif | ||
| 202 | return (unsigned long) memsize; | ||
| 203 | } | ||
| 204 | |||
| 205 | static inline __init unsigned long __tprot(unsigned long addr) | 174 | static inline __init unsigned long __tprot(unsigned long addr) |
| 206 | { | 175 | { |
| 207 | int cc = -1; | 176 | int cc = -1; |
| @@ -218,6 +187,7 @@ static inline __init unsigned long __tprot(unsigned long addr) | |||
| 218 | 187 | ||
| 219 | /* Checking memory in 128KB increments. */ | 188 | /* Checking memory in 128KB increments. */ |
| 220 | #define CHUNK_INCR (1UL << 17) | 189 | #define CHUNK_INCR (1UL << 17) |
| 190 | #define ADDR2G (1UL << 31) | ||
| 221 | 191 | ||
| 222 | static noinline __init void find_memory_chunks(unsigned long memsize) | 192 | static noinline __init void find_memory_chunks(unsigned long memsize) |
| 223 | { | 193 | { |
| @@ -293,7 +263,7 @@ static noinline __init void setup_lowcore_early(void) | |||
| 293 | */ | 263 | */ |
| 294 | void __init startup_init(void) | 264 | void __init startup_init(void) |
| 295 | { | 265 | { |
| 296 | unsigned long memsize; | 266 | unsigned long long memsize; |
| 297 | 267 | ||
| 298 | ipl_save_parameters(); | 268 | ipl_save_parameters(); |
| 299 | clear_bss_section(); | 269 | clear_bss_section(); |
| @@ -305,8 +275,17 @@ void __init startup_init(void) | |||
| 305 | sort_main_extable(); | 275 | sort_main_extable(); |
| 306 | setup_lowcore_early(); | 276 | setup_lowcore_early(); |
| 307 | sclp_readinfo_early(); | 277 | sclp_readinfo_early(); |
| 278 | sclp_facilities_detect(); | ||
| 308 | memsize = sclp_memory_detect(); | 279 | memsize = sclp_memory_detect(); |
| 280 | #ifndef CONFIG_64BIT | ||
| 281 | /* | ||
| 282 | * Can't deal with more than 2G in 31 bit addressing mode, so | ||
| 283 | * limit the value in order to avoid strange side effects. | ||
| 284 | */ | ||
| 285 | if (memsize > ADDR2G) | ||
| 286 | memsize = ADDR2G; | ||
| 287 | #endif | ||
| 309 | if (memory_fast_detect() < 0) | 288 | if (memory_fast_detect() < 0) |
| 310 | find_memory_chunks(memsize); | 289 | find_memory_chunks((unsigned long) memsize); |
| 311 | lockdep_on(); | 290 | lockdep_on(); |
| 312 | } | 291 | } |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 6234c6978a1f..bc7ff3658c3d 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
| @@ -107,6 +107,11 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
| 107 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 | 107 | l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 |
| 108 | .endm | 108 | .endm |
| 109 | 109 | ||
| 110 | .macro SAVE_ALL_SVC psworg,savearea | ||
| 111 | la %r12,\psworg | ||
| 112 | l %r15,__LC_KERNEL_STACK # problem state -> load ksp | ||
| 113 | .endm | ||
| 114 | |||
| 110 | .macro SAVE_ALL_SYNC psworg,savearea | 115 | .macro SAVE_ALL_SYNC psworg,savearea |
| 111 | la %r12,\psworg | 116 | la %r12,\psworg |
| 112 | tm \psworg+1,0x01 # test problem state bit | 117 | tm \psworg+1,0x01 # test problem state bit |
| @@ -218,7 +223,7 @@ system_call: | |||
| 218 | STORE_TIMER __LC_SYNC_ENTER_TIMER | 223 | STORE_TIMER __LC_SYNC_ENTER_TIMER |
| 219 | sysc_saveall: | 224 | sysc_saveall: |
| 220 | SAVE_ALL_BASE __LC_SAVE_AREA | 225 | SAVE_ALL_BASE __LC_SAVE_AREA |
| 221 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 226 | SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
| 222 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 227 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
| 223 | lh %r7,0x8a # get svc number from lowcore | 228 | lh %r7,0x8a # get svc number from lowcore |
| 224 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 229 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 685f11faa4bc..2a7b1304418b 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
| @@ -99,6 +99,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ | |||
| 99 | larl %r13,system_call | 99 | larl %r13,system_call |
| 100 | .endm | 100 | .endm |
| 101 | 101 | ||
| 102 | .macro SAVE_ALL_SVC psworg,savearea | ||
| 103 | la %r12,\psworg | ||
| 104 | lg %r15,__LC_KERNEL_STACK # problem state -> load ksp | ||
| 105 | .endm | ||
| 106 | |||
| 102 | .macro SAVE_ALL_SYNC psworg,savearea | 107 | .macro SAVE_ALL_SYNC psworg,savearea |
| 103 | la %r12,\psworg | 108 | la %r12,\psworg |
| 104 | tm \psworg+1,0x01 # test problem state bit | 109 | tm \psworg+1,0x01 # test problem state bit |
| @@ -207,7 +212,7 @@ system_call: | |||
| 207 | STORE_TIMER __LC_SYNC_ENTER_TIMER | 212 | STORE_TIMER __LC_SYNC_ENTER_TIMER |
| 208 | sysc_saveall: | 213 | sysc_saveall: |
| 209 | SAVE_ALL_BASE __LC_SAVE_AREA | 214 | SAVE_ALL_BASE __LC_SAVE_AREA |
| 210 | SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 215 | SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
| 211 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA | 216 | CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA |
| 212 | llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore | 217 | llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore |
| 213 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | 218 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index 367caf92ea78..82b131ddd7ff 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
| @@ -25,10 +25,6 @@ | |||
| 25 | 25 | ||
| 26 | #define IPL_PARM_BLOCK_VERSION 0 | 26 | #define IPL_PARM_BLOCK_VERSION 0 |
| 27 | 27 | ||
| 28 | #define SCCB_VALID (s390_readinfo_sccb.header.response_code == 0x10) | ||
| 29 | #define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm) | ||
| 30 | #define SCCB_FLAG (s390_readinfo_sccb.flags) | ||
| 31 | |||
| 32 | #define IPL_UNKNOWN_STR "unknown" | 28 | #define IPL_UNKNOWN_STR "unknown" |
| 33 | #define IPL_CCW_STR "ccw" | 29 | #define IPL_CCW_STR "ccw" |
| 34 | #define IPL_FCP_STR "fcp" | 30 | #define IPL_FCP_STR "fcp" |
| @@ -146,6 +142,8 @@ static struct ipl_parameter_block *dump_block_ccw; | |||
| 146 | 142 | ||
| 147 | static enum shutdown_action on_panic_action = SHUTDOWN_STOP; | 143 | static enum shutdown_action on_panic_action = SHUTDOWN_STOP; |
| 148 | 144 | ||
| 145 | static struct sclp_ipl_info sclp_ipl_info; | ||
| 146 | |||
| 149 | int diag308(unsigned long subcode, void *addr) | 147 | int diag308(unsigned long subcode, void *addr) |
| 150 | { | 148 | { |
| 151 | register unsigned long _addr asm("0") = (unsigned long) addr; | 149 | register unsigned long _addr asm("0") = (unsigned long) addr; |
| @@ -375,9 +373,9 @@ static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page) | |||
| 375 | { | 373 | { |
| 376 | char loadparm[LOADPARM_LEN + 1] = {}; | 374 | char loadparm[LOADPARM_LEN + 1] = {}; |
| 377 | 375 | ||
| 378 | if (!SCCB_VALID) | 376 | if (!sclp_ipl_info.is_valid) |
| 379 | return sprintf(page, "#unknown#\n"); | 377 | return sprintf(page, "#unknown#\n"); |
| 380 | memcpy(loadparm, SCCB_LOADPARM, LOADPARM_LEN); | 378 | memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN); |
| 381 | EBCASC(loadparm, LOADPARM_LEN); | 379 | EBCASC(loadparm, LOADPARM_LEN); |
| 382 | strstrip(loadparm); | 380 | strstrip(loadparm); |
| 383 | return sprintf(page, "%s\n", loadparm); | 381 | return sprintf(page, "%s\n", loadparm); |
| @@ -910,9 +908,9 @@ static int __init reipl_ccw_init(void) | |||
| 910 | reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; | 908 | reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; |
| 911 | reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; | 909 | reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; |
| 912 | /* check if read scp info worked and set loadparm */ | 910 | /* check if read scp info worked and set loadparm */ |
| 913 | if (SCCB_VALID) | 911 | if (sclp_ipl_info.is_valid) |
| 914 | memcpy(reipl_block_ccw->ipl_info.ccw.load_param, | 912 | memcpy(reipl_block_ccw->ipl_info.ccw.load_param, |
| 915 | SCCB_LOADPARM, LOADPARM_LEN); | 913 | &sclp_ipl_info.loadparm, LOADPARM_LEN); |
| 916 | else | 914 | else |
| 917 | /* read scp info failed: set empty loadparm (EBCDIC blanks) */ | 915 | /* read scp info failed: set empty loadparm (EBCDIC blanks) */ |
| 918 | memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, | 916 | memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, |
| @@ -1007,7 +1005,7 @@ static int __init dump_fcp_init(void) | |||
| 1007 | { | 1005 | { |
| 1008 | int rc; | 1006 | int rc; |
| 1009 | 1007 | ||
| 1010 | if(!(SCCB_FLAG & 0x2) || !SCCB_VALID) | 1008 | if (!sclp_ipl_info.has_dump) |
| 1011 | return 0; /* LDIPL DUMP is not installed */ | 1009 | return 0; /* LDIPL DUMP is not installed */ |
| 1012 | if (!diag308_set_works) | 1010 | if (!diag308_set_works) |
| 1013 | return 0; | 1011 | return 0; |
| @@ -1088,6 +1086,7 @@ static int __init s390_ipl_init(void) | |||
| 1088 | { | 1086 | { |
| 1089 | int rc; | 1087 | int rc; |
| 1090 | 1088 | ||
| 1089 | sclp_get_ipl_info(&sclp_ipl_info); | ||
| 1091 | reipl_probe(); | 1090 | reipl_probe(); |
| 1092 | rc = ipl_init(); | 1091 | rc = ipl_init(); |
| 1093 | if (rc) | 1092 | if (rc) |
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index eb43c3b31269..441975b796fb 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
| @@ -93,8 +93,8 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code) | |||
| 93 | /* disable monitor call class 0 */ | 93 | /* disable monitor call class 0 */ |
| 94 | __ctl_clear_bit(8, 15); | 94 | __ctl_clear_bit(8, 15); |
| 95 | 95 | ||
| 96 | atomic_notifier_call_chain(&idle_chain, CPU_NOT_IDLE, | 96 | atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE, |
| 97 | (void *)(long) smp_processor_id()); | 97 | (void *)(long) smp_processor_id()); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | extern void s390_handle_mcck(void); | 100 | extern void s390_handle_mcck(void); |
| @@ -115,7 +115,7 @@ static void default_idle(void) | |||
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | rc = atomic_notifier_call_chain(&idle_chain, | 117 | rc = atomic_notifier_call_chain(&idle_chain, |
| 118 | CPU_IDLE, (void *)(long) cpu); | 118 | S390_CPU_IDLE, (void *)(long) cpu); |
| 119 | if (rc != NOTIFY_OK && rc != NOTIFY_DONE) | 119 | if (rc != NOTIFY_OK && rc != NOTIFY_DONE) |
| 120 | BUG(); | 120 | BUG(); |
| 121 | if (rc != NOTIFY_OK) { | 121 | if (rc != NOTIFY_OK) { |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 8ff2feaf9b00..182c085ae4dd 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
| @@ -410,58 +410,40 @@ EXPORT_SYMBOL(smp_ctl_clear_bit); | |||
| 410 | unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \ | 410 | unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \ |
| 411 | __attribute__((__section__(".data"))); | 411 | __attribute__((__section__(".data"))); |
| 412 | 412 | ||
| 413 | static void __init smp_get_save_areas(void) | 413 | static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) |
| 414 | { | 414 | { |
| 415 | unsigned int cpu, cpu_num, rc; | ||
| 416 | __u16 boot_cpu_addr; | ||
| 417 | |||
| 418 | if (ipl_info.type != IPL_TYPE_FCP_DUMP) | 415 | if (ipl_info.type != IPL_TYPE_FCP_DUMP) |
| 419 | return; | 416 | return; |
| 420 | boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; | 417 | if (cpu >= NR_CPUS) { |
| 421 | cpu_num = 1; | 418 | printk(KERN_WARNING "Registers for cpu %i not saved since dump " |
| 422 | for (cpu = 0; cpu <= 65535; cpu++) { | 419 | "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS); |
| 423 | if ((u16) cpu == boot_cpu_addr) | 420 | return; |
| 424 | continue; | ||
| 425 | __cpu_logical_map[1] = (__u16) cpu; | ||
| 426 | if (signal_processor(1, sigp_sense) == sigp_not_operational) | ||
| 427 | continue; | ||
| 428 | if (cpu_num >= NR_CPUS) { | ||
| 429 | printk("WARNING: Registers for cpu %i are not " | ||
| 430 | "saved, since dump kernel was compiled with" | ||
| 431 | "NR_CPUS=%i!\n", cpu_num, NR_CPUS); | ||
| 432 | continue; | ||
| 433 | } | ||
| 434 | zfcpdump_save_areas[cpu_num] = | ||
| 435 | alloc_bootmem(sizeof(union save_area)); | ||
| 436 | while (1) { | ||
| 437 | rc = signal_processor(1, sigp_stop_and_store_status); | ||
| 438 | if (rc != sigp_busy) | ||
| 439 | break; | ||
| 440 | cpu_relax(); | ||
| 441 | } | ||
| 442 | memcpy(zfcpdump_save_areas[cpu_num], | ||
| 443 | (void *)(unsigned long) store_prefix() + | ||
| 444 | SAVE_AREA_BASE, SAVE_AREA_SIZE); | ||
| 445 | #ifdef __s390x__ | ||
| 446 | /* copy original prefix register */ | ||
| 447 | zfcpdump_save_areas[cpu_num]->s390x.pref_reg = | ||
| 448 | zfcpdump_prefix_array[cpu_num]; | ||
| 449 | #endif | ||
| 450 | cpu_num++; | ||
| 451 | } | 421 | } |
| 422 | zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area)); | ||
| 423 | __cpu_logical_map[1] = (__u16) phy_cpu; | ||
| 424 | while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy) | ||
| 425 | cpu_relax(); | ||
| 426 | memcpy(zfcpdump_save_areas[cpu], | ||
| 427 | (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, | ||
| 428 | SAVE_AREA_SIZE); | ||
| 429 | #ifdef CONFIG_64BIT | ||
| 430 | /* copy original prefix register */ | ||
| 431 | zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu]; | ||
| 432 | #endif | ||
| 452 | } | 433 | } |
| 453 | 434 | ||
| 454 | union save_area *zfcpdump_save_areas[NR_CPUS + 1]; | 435 | union save_area *zfcpdump_save_areas[NR_CPUS + 1]; |
| 455 | EXPORT_SYMBOL_GPL(zfcpdump_save_areas); | 436 | EXPORT_SYMBOL_GPL(zfcpdump_save_areas); |
| 456 | 437 | ||
| 457 | #else | 438 | #else |
| 458 | #define smp_get_save_areas() do { } while (0) | 439 | |
| 459 | #endif | 440 | static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { } |
| 441 | |||
| 442 | #endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */ | ||
| 460 | 443 | ||
| 461 | /* | 444 | /* |
| 462 | * Lets check how many CPUs we have. | 445 | * Lets check how many CPUs we have. |
| 463 | */ | 446 | */ |
| 464 | |||
| 465 | static unsigned int __init smp_count_cpus(void) | 447 | static unsigned int __init smp_count_cpus(void) |
| 466 | { | 448 | { |
| 467 | unsigned int cpu, num_cpus; | 449 | unsigned int cpu, num_cpus; |
| @@ -470,7 +452,6 @@ static unsigned int __init smp_count_cpus(void) | |||
| 470 | /* | 452 | /* |
| 471 | * cpu 0 is the boot cpu. See smp_prepare_boot_cpu. | 453 | * cpu 0 is the boot cpu. See smp_prepare_boot_cpu. |
| 472 | */ | 454 | */ |
| 473 | |||
| 474 | boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; | 455 | boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; |
| 475 | current_thread_info()->cpu = 0; | 456 | current_thread_info()->cpu = 0; |
| 476 | num_cpus = 1; | 457 | num_cpus = 1; |
| @@ -480,12 +461,11 @@ static unsigned int __init smp_count_cpus(void) | |||
| 480 | __cpu_logical_map[1] = (__u16) cpu; | 461 | __cpu_logical_map[1] = (__u16) cpu; |
| 481 | if (signal_processor(1, sigp_sense) == sigp_not_operational) | 462 | if (signal_processor(1, sigp_sense) == sigp_not_operational) |
| 482 | continue; | 463 | continue; |
| 464 | smp_get_save_area(num_cpus, cpu); | ||
| 483 | num_cpus++; | 465 | num_cpus++; |
| 484 | } | 466 | } |
| 485 | |||
| 486 | printk("Detected %d CPU's\n", (int) num_cpus); | 467 | printk("Detected %d CPU's\n", (int) num_cpus); |
| 487 | printk("Boot cpu address %2X\n", boot_cpu_addr); | 468 | printk("Boot cpu address %2X\n", boot_cpu_addr); |
| 488 | |||
| 489 | return num_cpus; | 469 | return num_cpus; |
| 490 | } | 470 | } |
| 491 | 471 | ||
| @@ -606,7 +586,6 @@ void __init smp_setup_cpu_possible_map(void) | |||
| 606 | { | 586 | { |
| 607 | unsigned int phy_cpus, pos_cpus, cpu; | 587 | unsigned int phy_cpus, pos_cpus, cpu; |
| 608 | 588 | ||
| 609 | smp_get_save_areas(); | ||
| 610 | phy_cpus = smp_count_cpus(); | 589 | phy_cpus = smp_count_cpus(); |
| 611 | pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS); | 590 | pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS); |
| 612 | 591 | ||
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index 9c2872a7cca7..48dae49bc1ec 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
| @@ -226,10 +226,10 @@ static int nohz_idle_notify(struct notifier_block *self, | |||
| 226 | unsigned long action, void *hcpu) | 226 | unsigned long action, void *hcpu) |
| 227 | { | 227 | { |
| 228 | switch (action) { | 228 | switch (action) { |
| 229 | case CPU_IDLE: | 229 | case S390_CPU_IDLE: |
| 230 | stop_hz_timer(); | 230 | stop_hz_timer(); |
| 231 | break; | 231 | break; |
| 232 | case CPU_NOT_IDLE: | 232 | case S390_CPU_NOT_IDLE: |
| 233 | start_hz_timer(); | 233 | start_hz_timer(); |
| 234 | break; | 234 | break; |
| 235 | } | 235 | } |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 1e1a6ee2cac1..b6ed143e8597 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
| @@ -545,10 +545,10 @@ static int vtimer_idle_notify(struct notifier_block *self, | |||
| 545 | unsigned long action, void *hcpu) | 545 | unsigned long action, void *hcpu) |
| 546 | { | 546 | { |
| 547 | switch (action) { | 547 | switch (action) { |
| 548 | case CPU_IDLE: | 548 | case S390_CPU_IDLE: |
| 549 | stop_cpu_timer(); | 549 | stop_cpu_timer(); |
| 550 | break; | 550 | break; |
| 551 | case CPU_NOT_IDLE: | 551 | case S390_CPU_NOT_IDLE: |
| 552 | start_cpu_timer(); | 552 | start_cpu_timer(); |
| 553 | break; | 553 | break; |
| 554 | } | 554 | } |
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile index 59aea65ce99f..52084436ab69 100644 --- a/arch/s390/lib/Makefile +++ b/arch/s390/lib/Makefile | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | EXTRA_AFLAGS := -traditional | 5 | EXTRA_AFLAGS := -traditional |
| 6 | 6 | ||
| 7 | lib-y += delay.o string.o uaccess_std.o uaccess_pt.o qrnnd.o | 7 | lib-y += delay.o string.o uaccess_std.o uaccess_pt.o |
| 8 | obj-$(CONFIG_32BIT) += div64.o | 8 | obj-$(CONFIG_32BIT) += div64.o qrnnd.o |
| 9 | lib-$(CONFIG_64BIT) += uaccess_mvcos.o | 9 | lib-$(CONFIG_64BIT) += uaccess_mvcos.o |
| 10 | lib-$(CONFIG_SMP) += spinlock.o | 10 | lib-$(CONFIG_SMP) += spinlock.o |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 8b3b0f4a157c..ac7e8ef504cb 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
| @@ -28,6 +28,7 @@ static struct proc_dir_entry *dasd_proc_root_entry = NULL; | |||
| 28 | static struct proc_dir_entry *dasd_devices_entry = NULL; | 28 | static struct proc_dir_entry *dasd_devices_entry = NULL; |
| 29 | static struct proc_dir_entry *dasd_statistics_entry = NULL; | 29 | static struct proc_dir_entry *dasd_statistics_entry = NULL; |
| 30 | 30 | ||
| 31 | #ifdef CONFIG_DASD_PROFILE | ||
| 31 | static char * | 32 | static char * |
| 32 | dasd_get_user_string(const char __user *user_buf, size_t user_len) | 33 | dasd_get_user_string(const char __user *user_buf, size_t user_len) |
| 33 | { | 34 | { |
| @@ -47,6 +48,7 @@ dasd_get_user_string(const char __user *user_buf, size_t user_len) | |||
| 47 | buffer[user_len] = 0; | 48 | buffer[user_len] = 0; |
| 48 | return buffer; | 49 | return buffer; |
| 49 | } | 50 | } |
| 51 | #endif /* CONFIG_DASD_PROFILE */ | ||
| 50 | 52 | ||
| 51 | static int | 53 | static int |
| 52 | dasd_devices_show(struct seq_file *m, void *v) | 54 | dasd_devices_show(struct seq_file *m, void *v) |
| @@ -167,6 +169,7 @@ dasd_calc_metrics(char *page, char **start, off_t off, | |||
| 167 | return len; | 169 | return len; |
| 168 | } | 170 | } |
| 169 | 171 | ||
| 172 | #ifdef CONFIG_DASD_PROFILE | ||
| 170 | static char * | 173 | static char * |
| 171 | dasd_statistics_array(char *str, unsigned int *array, int shift) | 174 | dasd_statistics_array(char *str, unsigned int *array, int shift) |
| 172 | { | 175 | { |
| @@ -180,6 +183,7 @@ dasd_statistics_array(char *str, unsigned int *array, int shift) | |||
| 180 | str += sprintf(str,"\n"); | 183 | str += sprintf(str,"\n"); |
| 181 | return str; | 184 | return str; |
| 182 | } | 185 | } |
| 186 | #endif /* CONFIG_DASD_PROFILE */ | ||
| 183 | 187 | ||
| 184 | static int | 188 | static int |
| 185 | dasd_statistics_read(char *page, char **start, off_t off, | 189 | dasd_statistics_read(char *page, char **start, off_t off, |
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index dbb99d1b6f57..c7318a125852 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h | |||
| @@ -72,6 +72,18 @@ typedef unsigned int sclp_cmdw_t; | |||
| 72 | 72 | ||
| 73 | typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ | 73 | typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ |
| 74 | 74 | ||
| 75 | struct sccb_header { | ||
| 76 | u16 length; | ||
| 77 | u8 function_code; | ||
| 78 | u8 control_mask[3]; | ||
| 79 | u16 response_code; | ||
| 80 | } __attribute__((packed)); | ||
| 81 | |||
| 82 | extern u64 sclp_facilities; | ||
| 83 | |||
| 84 | #define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) | ||
| 85 | #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) | ||
| 86 | |||
| 75 | struct gds_subvector { | 87 | struct gds_subvector { |
| 76 | u8 length; | 88 | u8 length; |
| 77 | u8 key; | 89 | u8 key; |
diff --git a/drivers/s390/char/sclp_chp.c b/drivers/s390/char/sclp_chp.c index a66b914519b5..c68f5e7e63a0 100644 --- a/drivers/s390/char/sclp_chp.c +++ b/drivers/s390/char/sclp_chp.c | |||
| @@ -55,6 +55,8 @@ static int do_configure(sclp_cmdw_t cmd) | |||
| 55 | struct chp_cfg_data *data; | 55 | struct chp_cfg_data *data; |
| 56 | int rc; | 56 | int rc; |
| 57 | 57 | ||
| 58 | if (!SCLP_HAS_CHP_RECONFIG) | ||
| 59 | return -EOPNOTSUPP; | ||
| 58 | /* Prepare sccb. */ | 60 | /* Prepare sccb. */ |
| 59 | data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | 61 | data = (struct chp_cfg_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); |
| 60 | if (!data) | 62 | if (!data) |
| @@ -152,6 +154,8 @@ int sclp_chp_read_info(struct sclp_chp_info *info) | |||
| 152 | struct chp_info_data *data; | 154 | struct chp_info_data *data; |
| 153 | int rc; | 155 | int rc; |
| 154 | 156 | ||
| 157 | if (!SCLP_HAS_CHP_INFO) | ||
| 158 | return -EOPNOTSUPP; | ||
| 155 | /* Prepare sccb. */ | 159 | /* Prepare sccb. */ |
| 156 | data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | 160 | data = (struct chp_info_data *) get_zeroed_page(GFP_KERNEL | GFP_DMA); |
| 157 | if (!data) | 161 | if (!data) |
diff --git a/drivers/s390/char/sclp_info.c b/drivers/s390/char/sclp_info.c index 7bcbe643b087..a1136e052750 100644 --- a/drivers/s390/char/sclp_info.c +++ b/drivers/s390/char/sclp_info.c | |||
| @@ -11,47 +11,106 @@ | |||
| 11 | #include <asm/sclp.h> | 11 | #include <asm/sclp.h> |
| 12 | #include "sclp.h" | 12 | #include "sclp.h" |
| 13 | 13 | ||
| 14 | struct sclp_readinfo_sccb s390_readinfo_sccb; | 14 | struct sclp_readinfo_sccb { |
| 15 | struct sccb_header header; /* 0-7 */ | ||
| 16 | u16 rnmax; /* 8-9 */ | ||
| 17 | u8 rnsize; /* 10 */ | ||
| 18 | u8 _reserved0[24 - 11]; /* 11-23 */ | ||
| 19 | u8 loadparm[8]; /* 24-31 */ | ||
| 20 | u8 _reserved1[48 - 32]; /* 32-47 */ | ||
| 21 | u64 facilities; /* 48-55 */ | ||
| 22 | u8 _reserved2[91 - 56]; /* 56-90 */ | ||
| 23 | u8 flags; /* 91 */ | ||
| 24 | u8 _reserved3[100 - 92]; /* 92-99 */ | ||
| 25 | u32 rnsize2; /* 100-103 */ | ||
| 26 | u64 rnmax2; /* 104-111 */ | ||
| 27 | u8 _reserved4[4096 - 112]; /* 112-4095 */ | ||
| 28 | } __attribute__((packed, aligned(4096))); | ||
| 29 | |||
| 30 | static struct sclp_readinfo_sccb __initdata early_readinfo_sccb; | ||
| 31 | static int __initdata early_readinfo_sccb_valid; | ||
| 32 | |||
| 33 | u64 sclp_facilities; | ||
| 15 | 34 | ||
| 16 | void __init sclp_readinfo_early(void) | 35 | void __init sclp_readinfo_early(void) |
| 17 | { | 36 | { |
| 18 | sclp_cmdw_t command; | ||
| 19 | struct sccb_header *sccb; | ||
| 20 | int ret; | 37 | int ret; |
| 38 | int i; | ||
| 39 | struct sclp_readinfo_sccb *sccb; | ||
| 40 | sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, | ||
| 41 | SCLP_CMDW_READ_SCP_INFO}; | ||
| 21 | 42 | ||
| 22 | __ctl_set_bit(0, 9); /* enable service signal subclass mask */ | 43 | /* Enable service signal subclass mask. */ |
| 23 | 44 | __ctl_set_bit(0, 9); | |
| 24 | sccb = &s390_readinfo_sccb.header; | 45 | sccb = &early_readinfo_sccb; |
| 25 | command = SCLP_CMDW_READ_SCP_INFO_FORCED; | 46 | for (i = 0; i < ARRAY_SIZE(commands); i++) { |
| 26 | while (1) { | 47 | do { |
| 27 | u16 response; | 48 | memset(sccb, 0, sizeof(*sccb)); |
| 28 | 49 | sccb->header.length = sizeof(*sccb); | |
| 29 | memset(&s390_readinfo_sccb, 0, sizeof(s390_readinfo_sccb)); | 50 | sccb->header.control_mask[2] = 0x80; |
| 30 | sccb->length = sizeof(s390_readinfo_sccb); | 51 | ret = sclp_service_call(commands[i], sccb); |
| 31 | sccb->control_mask[2] = 0x80; | 52 | } while (ret == -EBUSY); |
| 32 | |||
| 33 | ret = sclp_service_call(command, &s390_readinfo_sccb); | ||
| 34 | |||
| 35 | if (ret == -EIO) | ||
| 36 | goto out; | ||
| 37 | if (ret == -EBUSY) | ||
| 38 | continue; | ||
| 39 | 53 | ||
| 54 | if (ret) | ||
| 55 | break; | ||
| 40 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | | 56 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_EXT | |
| 41 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); | 57 | PSW_MASK_WAIT | PSW_DEFAULT_KEY); |
| 42 | local_irq_disable(); | 58 | local_irq_disable(); |
| 59 | /* | ||
| 60 | * Contents of the sccb might have changed | ||
| 61 | * therefore a barrier is needed. | ||
| 62 | */ | ||
| 43 | barrier(); | 63 | barrier(); |
| 64 | if (sccb->header.response_code == 0x10) { | ||
| 65 | early_readinfo_sccb_valid = 1; | ||
| 66 | break; | ||
| 67 | } | ||
| 68 | if (sccb->header.response_code != 0x1f0) | ||
| 69 | break; | ||
| 70 | } | ||
| 71 | /* Disable service signal subclass mask again. */ | ||
| 72 | __ctl_clear_bit(0, 9); | ||
| 73 | } | ||
| 44 | 74 | ||
| 45 | response = sccb->response_code; | 75 | void __init sclp_facilities_detect(void) |
| 76 | { | ||
| 77 | if (!early_readinfo_sccb_valid) | ||
| 78 | return; | ||
| 79 | sclp_facilities = early_readinfo_sccb.facilities; | ||
| 80 | } | ||
| 46 | 81 | ||
| 47 | if (response == 0x10) | 82 | unsigned long long __init sclp_memory_detect(void) |
| 48 | break; | 83 | { |
| 84 | unsigned long long memsize; | ||
| 85 | struct sclp_readinfo_sccb *sccb; | ||
| 49 | 86 | ||
| 50 | if (response != 0x1f0 || command == SCLP_CMDW_READ_SCP_INFO) | 87 | if (!early_readinfo_sccb_valid) |
| 51 | break; | 88 | return 0; |
| 89 | sccb = &early_readinfo_sccb; | ||
| 90 | if (sccb->rnsize) | ||
| 91 | memsize = sccb->rnsize << 20; | ||
| 92 | else | ||
| 93 | memsize = sccb->rnsize2 << 20; | ||
| 94 | if (sccb->rnmax) | ||
| 95 | memsize *= sccb->rnmax; | ||
| 96 | else | ||
| 97 | memsize *= sccb->rnmax2; | ||
| 98 | return memsize; | ||
| 99 | } | ||
| 52 | 100 | ||
| 53 | command = SCLP_CMDW_READ_SCP_INFO; | 101 | /* |
| 54 | } | 102 | * This function will be called after sclp_memory_detect(), which gets called |
| 55 | out: | 103 | * early from early.c code. Therefore the sccb should have valid contents. |
| 56 | __ctl_clear_bit(0, 9); /* disable service signal subclass mask */ | 104 | */ |
| 105 | void __init sclp_get_ipl_info(struct sclp_ipl_info *info) | ||
| 106 | { | ||
| 107 | struct sclp_readinfo_sccb *sccb; | ||
| 108 | |||
| 109 | if (!early_readinfo_sccb_valid) | ||
| 110 | return; | ||
| 111 | sccb = &early_readinfo_sccb; | ||
| 112 | info->is_valid = 1; | ||
| 113 | if (sccb->flags & 0x2) | ||
| 114 | info->has_dump = 1; | ||
| 115 | memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN); | ||
| 57 | } | 116 | } |
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c index fce3dac5cb3e..82e6a6b253eb 100644 --- a/drivers/s390/char/vmcp.c +++ b/drivers/s390/char/vmcp.c | |||
| @@ -175,13 +175,12 @@ static long vmcp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 175 | 175 | ||
| 176 | static const struct file_operations vmcp_fops = { | 176 | static const struct file_operations vmcp_fops = { |
| 177 | .owner = THIS_MODULE, | 177 | .owner = THIS_MODULE, |
| 178 | .open = &vmcp_open, | 178 | .open = vmcp_open, |
| 179 | .release = &vmcp_release, | 179 | .release = vmcp_release, |
| 180 | .read = &vmcp_read, | 180 | .read = vmcp_read, |
| 181 | .llseek = &no_llseek, | 181 | .write = vmcp_write, |
| 182 | .write = &vmcp_write, | 182 | .unlocked_ioctl = vmcp_ioctl, |
| 183 | .unlocked_ioctl = &vmcp_ioctl, | 183 | .compat_ioctl = vmcp_ioctl |
| 184 | .compat_ioctl = &vmcp_ioctl | ||
| 185 | }; | 184 | }; |
| 186 | 185 | ||
| 187 | static struct miscdevice vmcp_dev = { | 186 | static struct miscdevice vmcp_dev = { |
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index a5a00e9ae4d0..12f7a4ce82c1 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
| @@ -835,7 +835,7 @@ static void vmlogrdr_cleanup(void) | |||
| 835 | } | 835 | } |
| 836 | 836 | ||
| 837 | 837 | ||
| 838 | static int vmlogrdr_init(void) | 838 | static int __init vmlogrdr_init(void) |
| 839 | { | 839 | { |
| 840 | int rc; | 840 | int rc; |
| 841 | int i; | 841 | int i; |
| @@ -885,7 +885,7 @@ cleanup: | |||
| 885 | } | 885 | } |
| 886 | 886 | ||
| 887 | 887 | ||
| 888 | static void vmlogrdr_exit(void) | 888 | static void __exit vmlogrdr_exit(void) |
| 889 | { | 889 | { |
| 890 | vmlogrdr_cleanup(); | 890 | vmlogrdr_cleanup(); |
| 891 | printk (KERN_INFO "vmlogrdr: driver unloaded\n"); | 891 | printk (KERN_INFO "vmlogrdr: driver unloaded\n"); |
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 4e711a985d59..3712ede16723 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c | |||
| @@ -156,7 +156,7 @@ static int memcpy_real(void *dest, unsigned long src, size_t count) | |||
| 156 | return rc; | 156 | return rc; |
| 157 | } | 157 | } |
| 158 | 158 | ||
| 159 | static int memcpy_real_user(__user void *dest, unsigned long src, size_t count) | 159 | static int memcpy_real_user(void __user *dest, unsigned long src, size_t count) |
| 160 | { | 160 | { |
| 161 | static char buf[4096]; | 161 | static char buf[4096]; |
| 162 | int offs = 0, size; | 162 | int offs = 0, size; |
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 997f46874537..60b9347f7c92 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | /* | 27 | /* |
| 28 | * diag210 is used under VM to get information about a virtual device | 28 | * diag210 is used under VM to get information about a virtual device |
| 29 | */ | 29 | */ |
| 30 | #ifdef CONFIG_64BIT | ||
| 31 | int | 30 | int |
| 32 | diag210(struct diag210 * addr) | 31 | diag210(struct diag210 * addr) |
| 33 | { | 32 | { |
| @@ -43,6 +42,7 @@ diag210(struct diag210 * addr) | |||
| 43 | spin_lock_irqsave(&diag210_lock, flags); | 42 | spin_lock_irqsave(&diag210_lock, flags); |
| 44 | diag210_tmp = *addr; | 43 | diag210_tmp = *addr; |
| 45 | 44 | ||
| 45 | #ifdef CONFIG_64BIT | ||
| 46 | asm volatile( | 46 | asm volatile( |
| 47 | " lhi %0,-1\n" | 47 | " lhi %0,-1\n" |
| 48 | " sam31\n" | 48 | " sam31\n" |
| @@ -51,19 +51,8 @@ diag210(struct diag210 * addr) | |||
| 51 | " srl %0,28\n" | 51 | " srl %0,28\n" |
| 52 | "1: sam64\n" | 52 | "1: sam64\n" |
| 53 | EX_TABLE(0b,1b) | 53 | EX_TABLE(0b,1b) |
| 54 | : "=&d" (ccode) : "a" (__pa(&diag210_tmp)) : "cc", "memory"); | 54 | : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); |
| 55 | |||
| 56 | *addr = diag210_tmp; | ||
| 57 | spin_unlock_irqrestore(&diag210_lock, flags); | ||
| 58 | |||
| 59 | return ccode; | ||
| 60 | } | ||
| 61 | #else | 55 | #else |
| 62 | int | ||
| 63 | diag210(struct diag210 * addr) | ||
| 64 | { | ||
| 65 | int ccode; | ||
| 66 | |||
| 67 | asm volatile( | 56 | asm volatile( |
| 68 | " lhi %0,-1\n" | 57 | " lhi %0,-1\n" |
| 69 | " diag %1,0,0x210\n" | 58 | " diag %1,0,0x210\n" |
| @@ -71,11 +60,14 @@ diag210(struct diag210 * addr) | |||
| 71 | " srl %0,28\n" | 60 | " srl %0,28\n" |
| 72 | "1:\n" | 61 | "1:\n" |
| 73 | EX_TABLE(0b,1b) | 62 | EX_TABLE(0b,1b) |
| 74 | : "=&d" (ccode) : "a" (__pa(addr)) : "cc", "memory"); | 63 | : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); |
| 64 | #endif | ||
| 65 | |||
| 66 | *addr = diag210_tmp; | ||
| 67 | spin_unlock_irqrestore(&diag210_lock, flags); | ||
| 75 | 68 | ||
| 76 | return ccode; | 69 | return ccode; |
| 77 | } | 70 | } |
| 78 | #endif | ||
| 79 | 71 | ||
| 80 | /* | 72 | /* |
| 81 | * Input : | 73 | * Input : |
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 5aac0ec36368..90bd22014513 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
| @@ -43,6 +43,7 @@ static void ap_poll_all(unsigned long); | |||
| 43 | static void ap_poll_timeout(unsigned long); | 43 | static void ap_poll_timeout(unsigned long); |
| 44 | static int ap_poll_thread_start(void); | 44 | static int ap_poll_thread_start(void); |
| 45 | static void ap_poll_thread_stop(void); | 45 | static void ap_poll_thread_stop(void); |
| 46 | static void ap_request_timeout(unsigned long); | ||
| 46 | 47 | ||
| 47 | /** | 48 | /** |
| 48 | * Module description. | 49 | * Module description. |
| @@ -189,6 +190,7 @@ int ap_send(ap_qid_t qid, unsigned long long psmid, void *msg, size_t length) | |||
| 189 | case AP_RESPONSE_NORMAL: | 190 | case AP_RESPONSE_NORMAL: |
| 190 | return 0; | 191 | return 0; |
| 191 | case AP_RESPONSE_Q_FULL: | 192 | case AP_RESPONSE_Q_FULL: |
| 193 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
| 192 | return -EBUSY; | 194 | return -EBUSY; |
| 193 | default: /* Device is gone. */ | 195 | default: /* Device is gone. */ |
| 194 | return -ENODEV; | 196 | return -ENODEV; |
| @@ -252,6 +254,8 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length) | |||
| 252 | if (status.queue_empty) | 254 | if (status.queue_empty) |
| 253 | return -ENOENT; | 255 | return -ENOENT; |
| 254 | return -EBUSY; | 256 | return -EBUSY; |
| 257 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
| 258 | return -EBUSY; | ||
| 255 | default: | 259 | default: |
| 256 | return -ENODEV; | 260 | return -ENODEV; |
| 257 | } | 261 | } |
| @@ -326,11 +330,12 @@ static int ap_init_queue(ap_qid_t qid) | |||
| 326 | i = AP_MAX_RESET; /* return with -ENODEV */ | 330 | i = AP_MAX_RESET; /* return with -ENODEV */ |
| 327 | break; | 331 | break; |
| 328 | case AP_RESPONSE_RESET_IN_PROGRESS: | 332 | case AP_RESPONSE_RESET_IN_PROGRESS: |
| 333 | rc = -EBUSY; | ||
| 329 | case AP_RESPONSE_BUSY: | 334 | case AP_RESPONSE_BUSY: |
| 330 | default: | 335 | default: |
| 331 | break; | 336 | break; |
| 332 | } | 337 | } |
| 333 | if (rc != -ENODEV) | 338 | if (rc != -ENODEV && rc != -EBUSY) |
| 334 | break; | 339 | break; |
| 335 | if (i < AP_MAX_RESET - 1) { | 340 | if (i < AP_MAX_RESET - 1) { |
| 336 | udelay(5); | 341 | udelay(5); |
| @@ -341,6 +346,40 @@ static int ap_init_queue(ap_qid_t qid) | |||
| 341 | } | 346 | } |
| 342 | 347 | ||
| 343 | /** | 348 | /** |
| 349 | * Arm request timeout if a AP device was idle and a new request is submitted. | ||
| 350 | */ | ||
| 351 | static void ap_increase_queue_count(struct ap_device *ap_dev) | ||
| 352 | { | ||
| 353 | int timeout = ap_dev->drv->request_timeout; | ||
| 354 | |||
| 355 | ap_dev->queue_count++; | ||
| 356 | if (ap_dev->queue_count == 1) { | ||
| 357 | mod_timer(&ap_dev->timeout, jiffies + timeout); | ||
| 358 | ap_dev->reset = AP_RESET_ARMED; | ||
| 359 | } | ||
| 360 | } | ||
| 361 | |||
| 362 | /** | ||
| 363 | * AP device is still alive, re-schedule request timeout if there are still | ||
| 364 | * pending requests. | ||
| 365 | */ | ||
| 366 | static void ap_decrease_queue_count(struct ap_device *ap_dev) | ||
| 367 | { | ||
| 368 | int timeout = ap_dev->drv->request_timeout; | ||
| 369 | |||
| 370 | ap_dev->queue_count--; | ||
| 371 | if (ap_dev->queue_count > 0) | ||
| 372 | mod_timer(&ap_dev->timeout, jiffies + timeout); | ||
| 373 | else | ||
| 374 | /** | ||
| 375 | * The timeout timer should to be disabled now - since | ||
| 376 | * del_timer_sync() is very expensive, we just tell via the | ||
| 377 | * reset flag to ignore the pending timeout timer. | ||
| 378 | */ | ||
| 379 | ap_dev->reset = AP_RESET_IGNORE; | ||
| 380 | } | ||
| 381 | |||
| 382 | /** | ||
| 344 | * AP device related attributes. | 383 | * AP device related attributes. |
| 345 | */ | 384 | */ |
| 346 | static ssize_t ap_hwtype_show(struct device *dev, | 385 | static ssize_t ap_hwtype_show(struct device *dev, |
| @@ -498,6 +537,7 @@ static int ap_device_remove(struct device *dev) | |||
| 498 | struct ap_driver *ap_drv = ap_dev->drv; | 537 | struct ap_driver *ap_drv = ap_dev->drv; |
| 499 | 538 | ||
| 500 | ap_flush_queue(ap_dev); | 539 | ap_flush_queue(ap_dev); |
| 540 | del_timer_sync(&ap_dev->timeout); | ||
| 501 | if (ap_drv->remove) | 541 | if (ap_drv->remove) |
| 502 | ap_drv->remove(ap_dev); | 542 | ap_drv->remove(ap_dev); |
| 503 | spin_lock_bh(&ap_device_lock); | 543 | spin_lock_bh(&ap_device_lock); |
| @@ -759,17 +799,21 @@ static void ap_scan_bus(struct work_struct *unused) | |||
| 759 | __ap_scan_bus); | 799 | __ap_scan_bus); |
| 760 | rc = ap_query_queue(qid, &queue_depth, &device_type); | 800 | rc = ap_query_queue(qid, &queue_depth, &device_type); |
| 761 | if (dev) { | 801 | if (dev) { |
| 802 | if (rc == -EBUSY) { | ||
| 803 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
| 804 | schedule_timeout(AP_RESET_TIMEOUT); | ||
| 805 | rc = ap_query_queue(qid, &queue_depth, | ||
| 806 | &device_type); | ||
| 807 | } | ||
| 762 | ap_dev = to_ap_dev(dev); | 808 | ap_dev = to_ap_dev(dev); |
| 763 | spin_lock_bh(&ap_dev->lock); | 809 | spin_lock_bh(&ap_dev->lock); |
| 764 | if (rc || ap_dev->unregistered) { | 810 | if (rc || ap_dev->unregistered) { |
| 765 | spin_unlock_bh(&ap_dev->lock); | 811 | spin_unlock_bh(&ap_dev->lock); |
| 766 | put_device(dev); | ||
| 767 | device_unregister(dev); | 812 | device_unregister(dev); |
| 813 | put_device(dev); | ||
| 768 | continue; | 814 | continue; |
| 769 | } else | 815 | } |
| 770 | spin_unlock_bh(&ap_dev->lock); | 816 | spin_unlock_bh(&ap_dev->lock); |
| 771 | } | ||
| 772 | if (dev) { | ||
| 773 | put_device(dev); | 817 | put_device(dev); |
| 774 | continue; | 818 | continue; |
| 775 | } | 819 | } |
| @@ -788,6 +832,8 @@ static void ap_scan_bus(struct work_struct *unused) | |||
| 788 | INIT_LIST_HEAD(&ap_dev->pendingq); | 832 | INIT_LIST_HEAD(&ap_dev->pendingq); |
| 789 | INIT_LIST_HEAD(&ap_dev->requestq); | 833 | INIT_LIST_HEAD(&ap_dev->requestq); |
| 790 | INIT_LIST_HEAD(&ap_dev->list); | 834 | INIT_LIST_HEAD(&ap_dev->list); |
| 835 | setup_timer(&ap_dev->timeout, ap_request_timeout, | ||
| 836 | (unsigned long) ap_dev); | ||
| 791 | if (device_type == 0) | 837 | if (device_type == 0) |
| 792 | ap_probe_device_type(ap_dev); | 838 | ap_probe_device_type(ap_dev); |
| 793 | else | 839 | else |
| @@ -853,7 +899,7 @@ static int ap_poll_read(struct ap_device *ap_dev, unsigned long *flags) | |||
| 853 | switch (status.response_code) { | 899 | switch (status.response_code) { |
| 854 | case AP_RESPONSE_NORMAL: | 900 | case AP_RESPONSE_NORMAL: |
| 855 | atomic_dec(&ap_poll_requests); | 901 | atomic_dec(&ap_poll_requests); |
| 856 | ap_dev->queue_count--; | 902 | ap_decrease_queue_count(ap_dev); |
| 857 | list_for_each_entry(ap_msg, &ap_dev->pendingq, list) { | 903 | list_for_each_entry(ap_msg, &ap_dev->pendingq, list) { |
| 858 | if (ap_msg->psmid != ap_dev->reply->psmid) | 904 | if (ap_msg->psmid != ap_dev->reply->psmid) |
| 859 | continue; | 905 | continue; |
| @@ -904,7 +950,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) | |||
| 904 | switch (status.response_code) { | 950 | switch (status.response_code) { |
| 905 | case AP_RESPONSE_NORMAL: | 951 | case AP_RESPONSE_NORMAL: |
| 906 | atomic_inc(&ap_poll_requests); | 952 | atomic_inc(&ap_poll_requests); |
| 907 | ap_dev->queue_count++; | 953 | ap_increase_queue_count(ap_dev); |
| 908 | list_move_tail(&ap_msg->list, &ap_dev->pendingq); | 954 | list_move_tail(&ap_msg->list, &ap_dev->pendingq); |
| 909 | ap_dev->requestq_count--; | 955 | ap_dev->requestq_count--; |
| 910 | ap_dev->pendingq_count++; | 956 | ap_dev->pendingq_count++; |
| @@ -914,6 +960,7 @@ static int ap_poll_write(struct ap_device *ap_dev, unsigned long *flags) | |||
| 914 | *flags |= 2; | 960 | *flags |= 2; |
| 915 | break; | 961 | break; |
| 916 | case AP_RESPONSE_Q_FULL: | 962 | case AP_RESPONSE_Q_FULL: |
| 963 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
| 917 | *flags |= 2; | 964 | *flags |= 2; |
| 918 | break; | 965 | break; |
| 919 | case AP_RESPONSE_MESSAGE_TOO_BIG: | 966 | case AP_RESPONSE_MESSAGE_TOO_BIG: |
| @@ -960,10 +1007,11 @@ static int __ap_queue_message(struct ap_device *ap_dev, struct ap_message *ap_ms | |||
| 960 | list_add_tail(&ap_msg->list, &ap_dev->pendingq); | 1007 | list_add_tail(&ap_msg->list, &ap_dev->pendingq); |
| 961 | atomic_inc(&ap_poll_requests); | 1008 | atomic_inc(&ap_poll_requests); |
| 962 | ap_dev->pendingq_count++; | 1009 | ap_dev->pendingq_count++; |
| 963 | ap_dev->queue_count++; | 1010 | ap_increase_queue_count(ap_dev); |
| 964 | ap_dev->total_request_count++; | 1011 | ap_dev->total_request_count++; |
| 965 | break; | 1012 | break; |
| 966 | case AP_RESPONSE_Q_FULL: | 1013 | case AP_RESPONSE_Q_FULL: |
| 1014 | case AP_RESPONSE_RESET_IN_PROGRESS: | ||
| 967 | list_add_tail(&ap_msg->list, &ap_dev->requestq); | 1015 | list_add_tail(&ap_msg->list, &ap_dev->requestq); |
| 968 | ap_dev->requestq_count++; | 1016 | ap_dev->requestq_count++; |
| 969 | ap_dev->total_request_count++; | 1017 | ap_dev->total_request_count++; |
| @@ -1046,6 +1094,25 @@ static void ap_poll_timeout(unsigned long unused) | |||
| 1046 | } | 1094 | } |
| 1047 | 1095 | ||
| 1048 | /** | 1096 | /** |
| 1097 | * Reset a not responding AP device and move all requests from the | ||
| 1098 | * pending queue to the request queue. | ||
| 1099 | */ | ||
| 1100 | static void ap_reset(struct ap_device *ap_dev) | ||
| 1101 | { | ||
| 1102 | int rc; | ||
| 1103 | |||
| 1104 | ap_dev->reset = AP_RESET_IGNORE; | ||
| 1105 | atomic_sub(ap_dev->queue_count, &ap_poll_requests); | ||
| 1106 | ap_dev->queue_count = 0; | ||
| 1107 | list_splice_init(&ap_dev->pendingq, &ap_dev->requestq); | ||
| 1108 | ap_dev->requestq_count += ap_dev->pendingq_count; | ||
| 1109 | ap_dev->pendingq_count = 0; | ||
| 1110 | rc = ap_init_queue(ap_dev->qid); | ||
| 1111 | if (rc == -ENODEV) | ||
| 1112 | ap_dev->unregistered = 1; | ||
| 1113 | } | ||
| 1114 | |||
| 1115 | /** | ||
| 1049 | * Poll all AP devices on the bus in a round robin fashion. Continue | 1116 | * Poll all AP devices on the bus in a round robin fashion. Continue |
| 1050 | * polling until bit 2^0 of the control flags is not set. If bit 2^1 | 1117 | * polling until bit 2^0 of the control flags is not set. If bit 2^1 |
| 1051 | * of the control flags has been set arm the poll timer. | 1118 | * of the control flags has been set arm the poll timer. |
| @@ -1056,6 +1123,8 @@ static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags) | |||
| 1056 | if (!ap_dev->unregistered) { | 1123 | if (!ap_dev->unregistered) { |
| 1057 | if (ap_poll_queue(ap_dev, flags)) | 1124 | if (ap_poll_queue(ap_dev, flags)) |
| 1058 | ap_dev->unregistered = 1; | 1125 | ap_dev->unregistered = 1; |
| 1126 | if (ap_dev->reset == AP_RESET_DO) | ||
| 1127 | ap_reset(ap_dev); | ||
| 1059 | } | 1128 | } |
| 1060 | spin_unlock(&ap_dev->lock); | 1129 | spin_unlock(&ap_dev->lock); |
| 1061 | return 0; | 1130 | return 0; |
| @@ -1147,6 +1216,17 @@ static void ap_poll_thread_stop(void) | |||
| 1147 | mutex_unlock(&ap_poll_thread_mutex); | 1216 | mutex_unlock(&ap_poll_thread_mutex); |
| 1148 | } | 1217 | } |
| 1149 | 1218 | ||
| 1219 | /** | ||
| 1220 | * Handling of request timeouts | ||
| 1221 | */ | ||
| 1222 | static void ap_request_timeout(unsigned long data) | ||
| 1223 | { | ||
| 1224 | struct ap_device *ap_dev = (struct ap_device *) data; | ||
| 1225 | |||
| 1226 | if (ap_dev->reset == AP_RESET_ARMED) | ||
| 1227 | ap_dev->reset = AP_RESET_DO; | ||
| 1228 | } | ||
| 1229 | |||
| 1150 | static void ap_reset_domain(void) | 1230 | static void ap_reset_domain(void) |
| 1151 | { | 1231 | { |
| 1152 | int i; | 1232 | int i; |
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 008559ea742b..87c2d6442875 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h | |||
| @@ -33,6 +33,7 @@ | |||
| 33 | #define AP_DEVICES 64 /* Number of AP devices. */ | 33 | #define AP_DEVICES 64 /* Number of AP devices. */ |
| 34 | #define AP_DOMAINS 16 /* Number of AP domains. */ | 34 | #define AP_DOMAINS 16 /* Number of AP domains. */ |
| 35 | #define AP_MAX_RESET 90 /* Maximum number of resets. */ | 35 | #define AP_MAX_RESET 90 /* Maximum number of resets. */ |
| 36 | #define AP_RESET_TIMEOUT (HZ/2) /* Time in ticks for reset timeouts. */ | ||
| 36 | #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ | 37 | #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ |
| 37 | #define AP_POLL_TIME 1 /* Time in ticks between receive polls. */ | 38 | #define AP_POLL_TIME 1 /* Time in ticks between receive polls. */ |
| 38 | 39 | ||
| @@ -83,6 +84,13 @@ struct ap_queue_status { | |||
| 83 | #define AP_DEVICE_TYPE_CEX2A 6 | 84 | #define AP_DEVICE_TYPE_CEX2A 6 |
| 84 | #define AP_DEVICE_TYPE_CEX2C 7 | 85 | #define AP_DEVICE_TYPE_CEX2C 7 |
| 85 | 86 | ||
| 87 | /** | ||
| 88 | * AP reset flag states | ||
| 89 | */ | ||
| 90 | #define AP_RESET_IGNORE 0 /* request timeout will be ignored */ | ||
| 91 | #define AP_RESET_ARMED 1 /* request timeout timer is active */ | ||
| 92 | #define AP_RESET_DO 2 /* AP reset required */ | ||
| 93 | |||
| 86 | struct ap_device; | 94 | struct ap_device; |
| 87 | struct ap_message; | 95 | struct ap_message; |
| 88 | 96 | ||
| @@ -95,6 +103,7 @@ struct ap_driver { | |||
| 95 | /* receive is called from tasklet context */ | 103 | /* receive is called from tasklet context */ |
| 96 | void (*receive)(struct ap_device *, struct ap_message *, | 104 | void (*receive)(struct ap_device *, struct ap_message *, |
| 97 | struct ap_message *); | 105 | struct ap_message *); |
| 106 | int request_timeout; /* request timeout in jiffies */ | ||
| 98 | }; | 107 | }; |
| 99 | 108 | ||
| 100 | #define to_ap_drv(x) container_of((x), struct ap_driver, driver) | 109 | #define to_ap_drv(x) container_of((x), struct ap_driver, driver) |
| @@ -112,6 +121,8 @@ struct ap_device { | |||
| 112 | int queue_depth; /* AP queue depth.*/ | 121 | int queue_depth; /* AP queue depth.*/ |
| 113 | int device_type; /* AP device type. */ | 122 | int device_type; /* AP device type. */ |
| 114 | int unregistered; /* marks AP device as unregistered */ | 123 | int unregistered; /* marks AP device as unregistered */ |
| 124 | struct timer_list timeout; /* Timer for request timeouts. */ | ||
| 125 | int reset; /* Reset required after req. timeout. */ | ||
| 115 | 126 | ||
| 116 | int queue_count; /* # messages currently on AP queue. */ | 127 | int queue_count; /* # messages currently on AP queue. */ |
| 117 | 128 | ||
diff --git a/drivers/s390/crypto/zcrypt_cex2a.c b/drivers/s390/crypto/zcrypt_cex2a.c index 5bb13a9d0898..08657f604b8c 100644 --- a/drivers/s390/crypto/zcrypt_cex2a.c +++ b/drivers/s390/crypto/zcrypt_cex2a.c | |||
| @@ -70,6 +70,7 @@ static struct ap_driver zcrypt_cex2a_driver = { | |||
| 70 | .remove = zcrypt_cex2a_remove, | 70 | .remove = zcrypt_cex2a_remove, |
| 71 | .receive = zcrypt_cex2a_receive, | 71 | .receive = zcrypt_cex2a_receive, |
| 72 | .ids = zcrypt_cex2a_ids, | 72 | .ids = zcrypt_cex2a_ids, |
| 73 | .request_timeout = CEX2A_CLEANUP_TIME, | ||
| 73 | }; | 74 | }; |
| 74 | 75 | ||
| 75 | /** | 76 | /** |
| @@ -306,18 +307,13 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_device *zdev, | |||
| 306 | goto out_free; | 307 | goto out_free; |
| 307 | init_completion(&work); | 308 | init_completion(&work); |
| 308 | ap_queue_message(zdev->ap_dev, &ap_msg); | 309 | ap_queue_message(zdev->ap_dev, &ap_msg); |
| 309 | rc = wait_for_completion_interruptible_timeout( | 310 | rc = wait_for_completion_interruptible(&work); |
| 310 | &work, CEX2A_CLEANUP_TIME); | 311 | if (rc == 0) |
| 311 | if (rc > 0) | ||
| 312 | rc = convert_response(zdev, &ap_msg, mex->outputdata, | 312 | rc = convert_response(zdev, &ap_msg, mex->outputdata, |
| 313 | mex->outputdatalength); | 313 | mex->outputdatalength); |
| 314 | else { | 314 | else |
| 315 | /* Signal pending or message timed out. */ | 315 | /* Signal pending. */ |
| 316 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 316 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
| 317 | if (rc == 0) | ||
| 318 | /* Message timed out. */ | ||
| 319 | rc = -ETIME; | ||
| 320 | } | ||
| 321 | out_free: | 317 | out_free: |
| 322 | kfree(ap_msg.message); | 318 | kfree(ap_msg.message); |
| 323 | return rc; | 319 | return rc; |
| @@ -348,18 +344,13 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_device *zdev, | |||
| 348 | goto out_free; | 344 | goto out_free; |
| 349 | init_completion(&work); | 345 | init_completion(&work); |
| 350 | ap_queue_message(zdev->ap_dev, &ap_msg); | 346 | ap_queue_message(zdev->ap_dev, &ap_msg); |
| 351 | rc = wait_for_completion_interruptible_timeout( | 347 | rc = wait_for_completion_interruptible(&work); |
| 352 | &work, CEX2A_CLEANUP_TIME); | 348 | if (rc == 0) |
| 353 | if (rc > 0) | ||
| 354 | rc = convert_response(zdev, &ap_msg, crt->outputdata, | 349 | rc = convert_response(zdev, &ap_msg, crt->outputdata, |
| 355 | crt->outputdatalength); | 350 | crt->outputdatalength); |
| 356 | else { | 351 | else |
| 357 | /* Signal pending or message timed out. */ | 352 | /* Signal pending. */ |
| 358 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 353 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
| 359 | if (rc == 0) | ||
| 360 | /* Message timed out. */ | ||
| 361 | rc = -ETIME; | ||
| 362 | } | ||
| 363 | out_free: | 354 | out_free: |
| 364 | kfree(ap_msg.message); | 355 | kfree(ap_msg.message); |
| 365 | return rc; | 356 | return rc; |
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c index 818ffe05ac00..6e93b4751782 100644 --- a/drivers/s390/crypto/zcrypt_pcica.c +++ b/drivers/s390/crypto/zcrypt_pcica.c | |||
| @@ -70,6 +70,7 @@ static struct ap_driver zcrypt_pcica_driver = { | |||
| 70 | .remove = zcrypt_pcica_remove, | 70 | .remove = zcrypt_pcica_remove, |
| 71 | .receive = zcrypt_pcica_receive, | 71 | .receive = zcrypt_pcica_receive, |
| 72 | .ids = zcrypt_pcica_ids, | 72 | .ids = zcrypt_pcica_ids, |
| 73 | .request_timeout = PCICA_CLEANUP_TIME, | ||
| 73 | }; | 74 | }; |
| 74 | 75 | ||
| 75 | /** | 76 | /** |
| @@ -290,18 +291,13 @@ static long zcrypt_pcica_modexpo(struct zcrypt_device *zdev, | |||
| 290 | goto out_free; | 291 | goto out_free; |
| 291 | init_completion(&work); | 292 | init_completion(&work); |
| 292 | ap_queue_message(zdev->ap_dev, &ap_msg); | 293 | ap_queue_message(zdev->ap_dev, &ap_msg); |
| 293 | rc = wait_for_completion_interruptible_timeout( | 294 | rc = wait_for_completion_interruptible(&work); |
| 294 | &work, PCICA_CLEANUP_TIME); | 295 | if (rc == 0) |
| 295 | if (rc > 0) | ||
| 296 | rc = convert_response(zdev, &ap_msg, mex->outputdata, | 296 | rc = convert_response(zdev, &ap_msg, mex->outputdata, |
| 297 | mex->outputdatalength); | 297 | mex->outputdatalength); |
| 298 | else { | 298 | else |
| 299 | /* Signal pending or message timed out. */ | 299 | /* Signal pending. */ |
| 300 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 300 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
| 301 | if (rc == 0) | ||
| 302 | /* Message timed out. */ | ||
| 303 | rc = -ETIME; | ||
| 304 | } | ||
| 305 | out_free: | 301 | out_free: |
| 306 | kfree(ap_msg.message); | 302 | kfree(ap_msg.message); |
| 307 | return rc; | 303 | return rc; |
| @@ -332,18 +328,13 @@ static long zcrypt_pcica_modexpo_crt(struct zcrypt_device *zdev, | |||
| 332 | goto out_free; | 328 | goto out_free; |
| 333 | init_completion(&work); | 329 | init_completion(&work); |
| 334 | ap_queue_message(zdev->ap_dev, &ap_msg); | 330 | ap_queue_message(zdev->ap_dev, &ap_msg); |
| 335 | rc = wait_for_completion_interruptible_timeout( | 331 | rc = wait_for_completion_interruptible(&work); |
| 336 | &work, PCICA_CLEANUP_TIME); | 332 | if (rc == 0) |
| 337 | if (rc > 0) | ||
| 338 | rc = convert_response(zdev, &ap_msg, crt->outputdata, | 333 | rc = convert_response(zdev, &ap_msg, crt->outputdata, |
| 339 | crt->outputdatalength); | 334 | crt->outputdatalength); |
| 340 | else { | 335 | else |
| 341 | /* Signal pending or message timed out. */ | 336 | /* Signal pending. */ |
| 342 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 337 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
| 343 | if (rc == 0) | ||
| 344 | /* Message timed out. */ | ||
| 345 | rc = -ETIME; | ||
| 346 | } | ||
| 347 | out_free: | 338 | out_free: |
| 348 | kfree(ap_msg.message); | 339 | kfree(ap_msg.message); |
| 349 | return rc; | 340 | return rc; |
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c index f295a403b29a..d6d59bf9ac38 100644 --- a/drivers/s390/crypto/zcrypt_pcicc.c +++ b/drivers/s390/crypto/zcrypt_pcicc.c | |||
| @@ -82,6 +82,7 @@ static struct ap_driver zcrypt_pcicc_driver = { | |||
| 82 | .remove = zcrypt_pcicc_remove, | 82 | .remove = zcrypt_pcicc_remove, |
| 83 | .receive = zcrypt_pcicc_receive, | 83 | .receive = zcrypt_pcicc_receive, |
| 84 | .ids = zcrypt_pcicc_ids, | 84 | .ids = zcrypt_pcicc_ids, |
| 85 | .request_timeout = PCICC_CLEANUP_TIME, | ||
| 85 | }; | 86 | }; |
| 86 | 87 | ||
| 87 | /** | 88 | /** |
| @@ -501,18 +502,13 @@ static long zcrypt_pcicc_modexpo(struct zcrypt_device *zdev, | |||
| 501 | goto out_free; | 502 | goto out_free; |
| 502 | init_completion(&work); | 503 | init_completion(&work); |
| 503 | ap_queue_message(zdev->ap_dev, &ap_msg); | 504 | ap_queue_message(zdev->ap_dev, &ap_msg); |
| 504 | rc = wait_for_completion_interruptible_timeout( | 505 | rc = wait_for_completion_interruptible(&work); |
| 505 | &work, PCICC_CLEANUP_TIME); | 506 | if (rc == 0) |
| 506 | if (rc > 0) | ||
| 507 | rc = convert_response(zdev, &ap_msg, mex->outputdata, | 507 | rc = convert_response(zdev, &ap_msg, mex->outputdata, |
| 508 | mex->outputdatalength); | 508 | mex->outputdatalength); |
| 509 | else { | 509 | else |
| 510 | /* Signal pending or message timed out. */ | 510 | /* Signal pending. */ |
| 511 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 511 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
| 512 | if (rc == 0) | ||
| 513 | /* Message timed out. */ | ||
| 514 | rc = -ETIME; | ||
| 515 | } | ||
| 516 | out_free: | 512 | out_free: |
| 517 | free_page((unsigned long) ap_msg.message); | 513 | free_page((unsigned long) ap_msg.message); |
| 518 | return rc; | 514 | return rc; |
| @@ -544,18 +540,13 @@ static long zcrypt_pcicc_modexpo_crt(struct zcrypt_device *zdev, | |||
| 544 | goto out_free; | 540 | goto out_free; |
| 545 | init_completion(&work); | 541 | init_completion(&work); |
| 546 | ap_queue_message(zdev->ap_dev, &ap_msg); | 542 | ap_queue_message(zdev->ap_dev, &ap_msg); |
| 547 | rc = wait_for_completion_interruptible_timeout( | 543 | rc = wait_for_completion_interruptible(&work); |
| 548 | &work, PCICC_CLEANUP_TIME); | 544 | if (rc == 0) |
| 549 | if (rc > 0) | ||
| 550 | rc = convert_response(zdev, &ap_msg, crt->outputdata, | 545 | rc = convert_response(zdev, &ap_msg, crt->outputdata, |
| 551 | crt->outputdatalength); | 546 | crt->outputdatalength); |
| 552 | else { | 547 | else |
| 553 | /* Signal pending or message timed out. */ | 548 | /* Signal pending. */ |
| 554 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 549 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
| 555 | if (rc == 0) | ||
| 556 | /* Message timed out. */ | ||
| 557 | rc = -ETIME; | ||
| 558 | } | ||
| 559 | out_free: | 550 | out_free: |
| 560 | free_page((unsigned long) ap_msg.message); | 551 | free_page((unsigned long) ap_msg.message); |
| 561 | return rc; | 552 | return rc; |
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 252443b6bd1b..64948788d301 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c | |||
| @@ -93,6 +93,7 @@ static struct ap_driver zcrypt_pcixcc_driver = { | |||
| 93 | .remove = zcrypt_pcixcc_remove, | 93 | .remove = zcrypt_pcixcc_remove, |
| 94 | .receive = zcrypt_pcixcc_receive, | 94 | .receive = zcrypt_pcixcc_receive, |
| 95 | .ids = zcrypt_pcixcc_ids, | 95 | .ids = zcrypt_pcixcc_ids, |
| 96 | .request_timeout = PCIXCC_CLEANUP_TIME, | ||
| 96 | }; | 97 | }; |
| 97 | 98 | ||
| 98 | /** | 99 | /** |
| @@ -641,18 +642,13 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev, | |||
| 641 | goto out_free; | 642 | goto out_free; |
| 642 | init_completion(&resp_type.work); | 643 | init_completion(&resp_type.work); |
| 643 | ap_queue_message(zdev->ap_dev, &ap_msg); | 644 | ap_queue_message(zdev->ap_dev, &ap_msg); |
| 644 | rc = wait_for_completion_interruptible_timeout( | 645 | rc = wait_for_completion_interruptible(&resp_type.work); |
| 645 | &resp_type.work, PCIXCC_CLEANUP_TIME); | 646 | if (rc == 0) |
| 646 | if (rc > 0) | ||
| 647 | rc = convert_response_ica(zdev, &ap_msg, mex->outputdata, | 647 | rc = convert_response_ica(zdev, &ap_msg, mex->outputdata, |
| 648 | mex->outputdatalength); | 648 | mex->outputdatalength); |
| 649 | else { | 649 | else |
| 650 | /* Signal pending or message timed out. */ | 650 | /* Signal pending. */ |
| 651 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 651 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
| 652 | if (rc == 0) | ||
| 653 | /* Message timed out. */ | ||
| 654 | rc = -ETIME; | ||
| 655 | } | ||
| 656 | out_free: | 652 | out_free: |
| 657 | free_page((unsigned long) ap_msg.message); | 653 | free_page((unsigned long) ap_msg.message); |
| 658 | return rc; | 654 | return rc; |
| @@ -685,18 +681,13 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev, | |||
| 685 | goto out_free; | 681 | goto out_free; |
| 686 | init_completion(&resp_type.work); | 682 | init_completion(&resp_type.work); |
| 687 | ap_queue_message(zdev->ap_dev, &ap_msg); | 683 | ap_queue_message(zdev->ap_dev, &ap_msg); |
| 688 | rc = wait_for_completion_interruptible_timeout( | 684 | rc = wait_for_completion_interruptible(&resp_type.work); |
| 689 | &resp_type.work, PCIXCC_CLEANUP_TIME); | 685 | if (rc == 0) |
| 690 | if (rc > 0) | ||
| 691 | rc = convert_response_ica(zdev, &ap_msg, crt->outputdata, | 686 | rc = convert_response_ica(zdev, &ap_msg, crt->outputdata, |
| 692 | crt->outputdatalength); | 687 | crt->outputdatalength); |
| 693 | else { | 688 | else |
| 694 | /* Signal pending or message timed out. */ | 689 | /* Signal pending. */ |
| 695 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 690 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
| 696 | if (rc == 0) | ||
| 697 | /* Message timed out. */ | ||
| 698 | rc = -ETIME; | ||
| 699 | } | ||
| 700 | out_free: | 691 | out_free: |
| 701 | free_page((unsigned long) ap_msg.message); | 692 | free_page((unsigned long) ap_msg.message); |
| 702 | return rc; | 693 | return rc; |
| @@ -729,17 +720,12 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, | |||
| 729 | goto out_free; | 720 | goto out_free; |
| 730 | init_completion(&resp_type.work); | 721 | init_completion(&resp_type.work); |
| 731 | ap_queue_message(zdev->ap_dev, &ap_msg); | 722 | ap_queue_message(zdev->ap_dev, &ap_msg); |
| 732 | rc = wait_for_completion_interruptible_timeout( | 723 | rc = wait_for_completion_interruptible(&resp_type.work); |
| 733 | &resp_type.work, PCIXCC_CLEANUP_TIME); | 724 | if (rc == 0) |
| 734 | if (rc > 0) | ||
| 735 | rc = convert_response_xcrb(zdev, &ap_msg, xcRB); | 725 | rc = convert_response_xcrb(zdev, &ap_msg, xcRB); |
| 736 | else { | 726 | else |
| 737 | /* Signal pending or message timed out. */ | 727 | /* Signal pending. */ |
| 738 | ap_cancel_message(zdev->ap_dev, &ap_msg); | 728 | ap_cancel_message(zdev->ap_dev, &ap_msg); |
| 739 | if (rc == 0) | ||
| 740 | /* Message timed out. */ | ||
| 741 | rc = -ETIME; | ||
| 742 | } | ||
| 743 | out_free: | 729 | out_free: |
| 744 | memset(ap_msg.message, 0x0, ap_msg.length); | 730 | memset(ap_msg.message, 0x0, ap_msg.length); |
| 745 | kfree(ap_msg.message); | 731 | kfree(ap_msg.message); |
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c index 9f7ad4244f63..1e064c4a4f86 100644 --- a/fs/partitions/ibm.c +++ b/fs/partitions/ibm.c | |||
| @@ -45,7 +45,7 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
| 45 | { | 45 | { |
| 46 | int blocksize, offset, size,res; | 46 | int blocksize, offset, size,res; |
| 47 | loff_t i_size; | 47 | loff_t i_size; |
| 48 | dasd_information_t *info; | 48 | dasd_information2_t *info; |
| 49 | struct hd_geometry *geo; | 49 | struct hd_geometry *geo; |
| 50 | char type[5] = {0,}; | 50 | char type[5] = {0,}; |
| 51 | char name[7] = {0,}; | 51 | char name[7] = {0,}; |
| @@ -64,14 +64,17 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
| 64 | if (i_size == 0) | 64 | if (i_size == 0) |
| 65 | goto out_exit; | 65 | goto out_exit; |
| 66 | 66 | ||
| 67 | if ((info = kmalloc(sizeof(dasd_information_t), GFP_KERNEL)) == NULL) | 67 | info = kmalloc(sizeof(dasd_information2_t), GFP_KERNEL); |
| 68 | if (info == NULL) | ||
| 68 | goto out_exit; | 69 | goto out_exit; |
| 69 | if ((geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL)) == NULL) | 70 | geo = kmalloc(sizeof(struct hd_geometry), GFP_KERNEL); |
| 71 | if (geo == NULL) | ||
| 70 | goto out_nogeo; | 72 | goto out_nogeo; |
| 71 | if ((label = kmalloc(sizeof(union label_t), GFP_KERNEL)) == NULL) | 73 | label = kmalloc(sizeof(union label_t), GFP_KERNEL); |
| 74 | if (label == NULL) | ||
| 72 | goto out_nolab; | 75 | goto out_nolab; |
| 73 | 76 | ||
| 74 | if (ioctl_by_bdev(bdev, BIODASDINFO, (unsigned long)info) != 0 || | 77 | if (ioctl_by_bdev(bdev, BIODASDINFO2, (unsigned long)info) != 0 || |
| 75 | ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) | 78 | ioctl_by_bdev(bdev, HDIO_GETGEO, (unsigned long)geo) != 0) |
| 76 | goto out_freeall; | 79 | goto out_freeall; |
| 77 | 80 | ||
| @@ -96,84 +99,108 @@ ibm_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
| 96 | res = 1; | 99 | res = 1; |
| 97 | 100 | ||
| 98 | /* | 101 | /* |
| 99 | * Three different types: CMS1, VOL1 and LNX1/unlabeled | 102 | * Three different formats: LDL, CDL and unformated disk |
| 103 | * | ||
| 104 | * identified by info->format | ||
| 105 | * | ||
| 106 | * unformated disks we do not have to care about | ||
| 100 | */ | 107 | */ |
| 101 | if (strncmp(type, "CMS1", 4) == 0) { | 108 | if (info->format == DASD_FORMAT_LDL) { |
| 102 | /* | 109 | if (strncmp(type, "CMS1", 4) == 0) { |
| 103 | * VM style CMS1 labeled disk | 110 | /* |
| 104 | */ | 111 | * VM style CMS1 labeled disk |
| 105 | if (label->cms.disk_offset != 0) { | 112 | */ |
| 106 | printk("CMS1/%8s(MDSK):", name); | 113 | if (label->cms.disk_offset != 0) { |
| 107 | /* disk is reserved minidisk */ | 114 | printk("CMS1/%8s(MDSK):", name); |
| 108 | blocksize = label->cms.block_size; | 115 | /* disk is reserved minidisk */ |
| 109 | offset = label->cms.disk_offset; | 116 | blocksize = label->cms.block_size; |
| 110 | size = (label->cms.block_count - 1) * (blocksize >> 9); | 117 | offset = label->cms.disk_offset; |
| 118 | size = (label->cms.block_count - 1) | ||
| 119 | * (blocksize >> 9); | ||
| 120 | } else { | ||
| 121 | printk("CMS1/%8s:", name); | ||
| 122 | offset = (info->label_block + 1); | ||
| 123 | size = i_size >> 9; | ||
| 124 | } | ||
| 111 | } else { | 125 | } else { |
| 112 | printk("CMS1/%8s:", name); | 126 | /* |
| 127 | * Old style LNX1 or unlabeled disk | ||
| 128 | */ | ||
| 129 | if (strncmp(type, "LNX1", 4) == 0) | ||
| 130 | printk ("LNX1/%8s:", name); | ||
| 131 | else | ||
| 132 | printk("(nonl)"); | ||
| 113 | offset = (info->label_block + 1); | 133 | offset = (info->label_block + 1); |
| 114 | size = i_size >> 9; | 134 | size = i_size >> 9; |
| 115 | } | 135 | } |
| 116 | put_partition(state, 1, offset*(blocksize >> 9), | 136 | put_partition(state, 1, offset*(blocksize >> 9), |
| 117 | size-offset*(blocksize >> 9)); | 137 | size-offset*(blocksize >> 9)); |
| 118 | } else if ((strncmp(type, "VOL1", 4) == 0) && | 138 | } else if (info->format == DASD_FORMAT_CDL) { |
| 119 | (!info->FBA_layout) && (!strcmp(info->type, "ECKD"))) { | ||
| 120 | /* | 139 | /* |
| 121 | * New style VOL1 labeled disk | 140 | * New style CDL formatted disk |
| 122 | */ | 141 | */ |
| 123 | unsigned int blk; | 142 | unsigned int blk; |
| 124 | int counter; | 143 | int counter; |
| 125 | 144 | ||
| 126 | printk("VOL1/%8s:", name); | ||
| 127 | |||
| 128 | /* get block number and read then go through format1 labels */ | ||
| 129 | blk = cchhb2blk(&label->vol.vtoc, geo) + 1; | ||
| 130 | counter = 0; | ||
| 131 | while ((data = read_dev_sector(bdev, blk*(blocksize/512), | ||
| 132 | §)) != NULL) { | ||
| 133 | struct vtoc_format1_label f1; | ||
| 134 | |||
| 135 | memcpy(&f1, data, sizeof(struct vtoc_format1_label)); | ||
| 136 | put_dev_sector(sect); | ||
| 137 | |||
| 138 | /* skip FMT4 / FMT5 / FMT7 labels */ | ||
| 139 | if (f1.DS1FMTID == _ascebc['4'] | ||
| 140 | || f1.DS1FMTID == _ascebc['5'] | ||
| 141 | || f1.DS1FMTID == _ascebc['7']) { | ||
| 142 | blk++; | ||
| 143 | continue; | ||
| 144 | } | ||
| 145 | |||
| 146 | /* only FMT1 valid at this point */ | ||
| 147 | if (f1.DS1FMTID != _ascebc['1']) | ||
| 148 | break; | ||
| 149 | |||
| 150 | /* OK, we got valid partition data */ | ||
| 151 | offset = cchh2blk(&f1.DS1EXT1.llimit, geo); | ||
| 152 | size = cchh2blk(&f1.DS1EXT1.ulimit, geo) - | ||
| 153 | offset + geo->sectors; | ||
| 154 | if (counter >= state->limit) | ||
| 155 | break; | ||
| 156 | put_partition(state, counter + 1, | ||
| 157 | offset * (blocksize >> 9), | ||
| 158 | size * (blocksize >> 9)); | ||
| 159 | counter++; | ||
| 160 | blk++; | ||
| 161 | } | ||
| 162 | if (!data) | ||
| 163 | /* Are we not supposed to report this ? */ | ||
| 164 | goto out_readerr; | ||
| 165 | } else { | ||
| 166 | /* | 145 | /* |
| 167 | * Old style LNX1 or unlabeled disk | 146 | * check if VOL1 label is available |
| 147 | * if not, something is wrong, skipping partition detection | ||
| 168 | */ | 148 | */ |
| 169 | if (strncmp(type, "LNX1", 4) == 0) | 149 | if (strncmp(type, "VOL1", 4) == 0) { |
| 170 | printk ("LNX1/%8s:", name); | 150 | printk("VOL1/%8s:", name); |
| 171 | else | 151 | /* |
| 172 | printk("(nonl)/%8s:", name); | 152 | * get block number and read then go through format1 |
| 173 | offset = (info->label_block + 1); | 153 | * labels |
| 174 | size = i_size >> 9; | 154 | */ |
| 175 | put_partition(state, 1, offset*(blocksize >> 9), | 155 | blk = cchhb2blk(&label->vol.vtoc, geo) + 1; |
| 176 | size-offset*(blocksize >> 9)); | 156 | counter = 0; |
| 157 | data = read_dev_sector(bdev, blk * (blocksize/512), | ||
| 158 | §); | ||
| 159 | while (data != NULL) { | ||
| 160 | struct vtoc_format1_label f1; | ||
| 161 | |||
| 162 | memcpy(&f1, data, | ||
| 163 | sizeof(struct vtoc_format1_label)); | ||
| 164 | put_dev_sector(sect); | ||
| 165 | |||
| 166 | /* skip FMT4 / FMT5 / FMT7 labels */ | ||
| 167 | if (f1.DS1FMTID == _ascebc['4'] | ||
| 168 | || f1.DS1FMTID == _ascebc['5'] | ||
| 169 | || f1.DS1FMTID == _ascebc['7']) { | ||
| 170 | blk++; | ||
| 171 | data = read_dev_sector(bdev, blk * | ||
| 172 | (blocksize/512), | ||
| 173 | §); | ||
| 174 | continue; | ||
| 175 | } | ||
| 176 | |||
| 177 | /* only FMT1 valid at this point */ | ||
| 178 | if (f1.DS1FMTID != _ascebc['1']) | ||
| 179 | break; | ||
| 180 | |||
| 181 | /* OK, we got valid partition data */ | ||
| 182 | offset = cchh2blk(&f1.DS1EXT1.llimit, geo); | ||
| 183 | size = cchh2blk(&f1.DS1EXT1.ulimit, geo) - | ||
| 184 | offset + geo->sectors; | ||
| 185 | if (counter >= state->limit) | ||
| 186 | break; | ||
| 187 | put_partition(state, counter + 1, | ||
| 188 | offset * (blocksize >> 9), | ||
| 189 | size * (blocksize >> 9)); | ||
| 190 | counter++; | ||
| 191 | blk++; | ||
| 192 | data = read_dev_sector(bdev, | ||
| 193 | blk * (blocksize/512), | ||
| 194 | §); | ||
| 195 | } | ||
| 196 | |||
| 197 | if (!data) | ||
| 198 | /* Are we not supposed to report this ? */ | ||
| 199 | goto out_readerr; | ||
| 200 | } else | ||
| 201 | printk(KERN_WARNING "Warning, expected Label VOL1 not " | ||
| 202 | "found, treating as CDL formated Disk"); | ||
| 203 | |||
| 177 | } | 204 | } |
| 178 | 205 | ||
| 179 | printk("\n"); | 206 | printk("\n"); |
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h index c17bdbf22067..ea486952f778 100644 --- a/include/asm-s390/atomic.h +++ b/include/asm-s390/atomic.h | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | typedef struct { | 26 | typedef struct { |
| 27 | volatile int counter; | 27 | int counter; |
| 28 | } __attribute__ ((aligned (4))) atomic_t; | 28 | } __attribute__ ((aligned (4))) atomic_t; |
| 29 | #define ATOMIC_INIT(i) { (i) } | 29 | #define ATOMIC_INIT(i) { (i) } |
| 30 | 30 | ||
| @@ -141,7 +141,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
| 141 | 141 | ||
| 142 | #ifdef __s390x__ | 142 | #ifdef __s390x__ |
| 143 | typedef struct { | 143 | typedef struct { |
| 144 | volatile long long counter; | 144 | long long counter; |
| 145 | } __attribute__ ((aligned (8))) atomic64_t; | 145 | } __attribute__ ((aligned (8))) atomic64_t; |
| 146 | #define ATOMIC64_INIT(i) { (i) } | 146 | #define ATOMIC64_INIT(i) { (i) } |
| 147 | 147 | ||
diff --git a/include/asm-s390/cmb.h b/include/asm-s390/cmb.h index 241756f80df3..021e7c3223ec 100644 --- a/include/asm-s390/cmb.h +++ b/include/asm-s390/cmb.h | |||
| @@ -88,7 +88,6 @@ extern u64 cmf_read(struct ccw_device *cdev, int index); | |||
| 88 | * any | 88 | * any |
| 89 | **/ | 89 | **/ |
| 90 | extern int cmf_readall(struct ccw_device *cdev, struct cmbdata*data); | 90 | extern int cmf_readall(struct ccw_device *cdev, struct cmbdata*data); |
| 91 | extern void cmf_reset(struct ccw_device *cdev); | ||
| 92 | 91 | ||
| 93 | #endif /* __KERNEL__ */ | 92 | #endif /* __KERNEL__ */ |
| 94 | #endif /* S390_CMB_H */ | 93 | #endif /* S390_CMB_H */ |
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h index 5cb480af65d5..3b972d4c6b29 100644 --- a/include/asm-s390/processor.h +++ b/include/asm-s390/processor.h | |||
| @@ -357,8 +357,8 @@ extern void (*s390_base_ext_handler_fn)(void); | |||
| 357 | /* | 357 | /* |
| 358 | * CPU idle notifier chain. | 358 | * CPU idle notifier chain. |
| 359 | */ | 359 | */ |
| 360 | #define CPU_IDLE 0 | 360 | #define S390_CPU_IDLE 0 |
| 361 | #define CPU_NOT_IDLE 1 | 361 | #define S390_CPU_NOT_IDLE 1 |
| 362 | 362 | ||
| 363 | struct notifier_block; | 363 | struct notifier_block; |
| 364 | int register_idle_notifier(struct notifier_block *nb); | 364 | int register_idle_notifier(struct notifier_block *nb); |
diff --git a/include/asm-s390/sclp.h b/include/asm-s390/sclp.h index 21ed64773210..cb9faf1ea5cf 100644 --- a/include/asm-s390/sclp.h +++ b/include/asm-s390/sclp.h | |||
| @@ -11,29 +11,6 @@ | |||
| 11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
| 12 | #include <asm/chpid.h> | 12 | #include <asm/chpid.h> |
| 13 | 13 | ||
| 14 | struct sccb_header { | ||
| 15 | u16 length; | ||
| 16 | u8 function_code; | ||
| 17 | u8 control_mask[3]; | ||
| 18 | u16 response_code; | ||
| 19 | } __attribute__((packed)); | ||
| 20 | |||
| 21 | #define LOADPARM_LEN 8 | ||
| 22 | |||
| 23 | struct sclp_readinfo_sccb { | ||
| 24 | struct sccb_header header; /* 0-7 */ | ||
| 25 | u16 rnmax; /* 8-9 */ | ||
| 26 | u8 rnsize; /* 10 */ | ||
| 27 | u8 _reserved0[24 - 11]; /* 11-23 */ | ||
| 28 | u8 loadparm[LOADPARM_LEN]; /* 24-31 */ | ||
| 29 | u8 _reserved1[91 - 32]; /* 32-90 */ | ||
| 30 | u8 flags; /* 91 */ | ||
| 31 | u8 _reserved2[100 - 92]; /* 92-99 */ | ||
| 32 | u32 rnsize2; /* 100-103 */ | ||
| 33 | u64 rnmax2; /* 104-111 */ | ||
| 34 | u8 _reserved3[4096 - 112]; /* 112-4095 */ | ||
| 35 | } __attribute__((packed, aligned(4096))); | ||
| 36 | |||
| 37 | #define SCLP_CHP_INFO_MASK_SIZE 32 | 14 | #define SCLP_CHP_INFO_MASK_SIZE 32 |
| 38 | 15 | ||
| 39 | struct sclp_chp_info { | 16 | struct sclp_chp_info { |
| @@ -42,12 +19,22 @@ struct sclp_chp_info { | |||
| 42 | u8 configured[SCLP_CHP_INFO_MASK_SIZE]; | 19 | u8 configured[SCLP_CHP_INFO_MASK_SIZE]; |
| 43 | }; | 20 | }; |
| 44 | 21 | ||
| 45 | extern struct sclp_readinfo_sccb s390_readinfo_sccb; | 22 | #define LOADPARM_LEN 8 |
| 46 | extern void sclp_readinfo_early(void); | 23 | |
| 47 | extern int sclp_sdias_blk_count(void); | 24 | struct sclp_ipl_info { |
| 48 | extern int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); | 25 | int is_valid; |
| 49 | extern int sclp_chp_configure(struct chp_id chpid); | 26 | int has_dump; |
| 50 | extern int sclp_chp_deconfigure(struct chp_id chpid); | 27 | char loadparm[LOADPARM_LEN]; |
| 51 | extern int sclp_chp_read_info(struct sclp_chp_info *info); | 28 | }; |
| 29 | |||
| 30 | void sclp_readinfo_early(void); | ||
| 31 | void sclp_facilities_detect(void); | ||
| 32 | unsigned long long sclp_memory_detect(void); | ||
| 33 | int sclp_sdias_blk_count(void); | ||
| 34 | int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); | ||
| 35 | int sclp_chp_configure(struct chp_id chpid); | ||
| 36 | int sclp_chp_deconfigure(struct chp_id chpid); | ||
| 37 | int sclp_chp_read_info(struct sclp_chp_info *info); | ||
| 38 | void sclp_get_ipl_info(struct sclp_ipl_info *info); | ||
| 52 | 39 | ||
| 53 | #endif /* _ASM_S390_SCLP_H */ | 40 | #endif /* _ASM_S390_SCLP_H */ |
diff --git a/include/asm-s390/sfp-machine.h b/include/asm-s390/sfp-machine.h index 8ca8c77b2d04..4e16aede4b06 100644 --- a/include/asm-s390/sfp-machine.h +++ b/include/asm-s390/sfp-machine.h | |||
| @@ -27,9 +27,9 @@ | |||
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | #define _FP_W_TYPE_SIZE 32 | 29 | #define _FP_W_TYPE_SIZE 32 |
| 30 | #define _FP_W_TYPE unsigned long | 30 | #define _FP_W_TYPE unsigned int |
| 31 | #define _FP_WS_TYPE signed long | 31 | #define _FP_WS_TYPE signed int |
| 32 | #define _FP_I_TYPE long | 32 | #define _FP_I_TYPE int |
| 33 | 33 | ||
| 34 | #define _FP_MUL_MEAT_S(R,X,Y) \ | 34 | #define _FP_MUL_MEAT_S(R,X,Y) \ |
| 35 | _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) | 35 | _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) |
diff --git a/include/asm-s390/sfp-util.h b/include/asm-s390/sfp-util.h index 8cabcd23d976..0addc6466d95 100644 --- a/include/asm-s390/sfp-util.h +++ b/include/asm-s390/sfp-util.h | |||
| @@ -51,6 +51,16 @@ | |||
| 51 | wl = __wl; \ | 51 | wl = __wl; \ |
| 52 | }) | 52 | }) |
| 53 | 53 | ||
| 54 | #ifdef __s390x__ | ||
| 55 | #define udiv_qrnnd(q, r, n1, n0, d) \ | ||
| 56 | do { unsigned long __n; \ | ||
| 57 | unsigned int __r, __d; \ | ||
| 58 | __n = ((unsigned long)(n1) << 32) + n0; \ | ||
| 59 | __d = (d); \ | ||
| 60 | (q) = __n / __d; \ | ||
| 61 | (r) = __n % __d; \ | ||
| 62 | } while (0) | ||
| 63 | #else | ||
| 54 | #define udiv_qrnnd(q, r, n1, n0, d) \ | 64 | #define udiv_qrnnd(q, r, n1, n0, d) \ |
| 55 | do { unsigned int __r; \ | 65 | do { unsigned int __r; \ |
| 56 | (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ | 66 | (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ |
| @@ -58,6 +68,7 @@ | |||
| 58 | } while (0) | 68 | } while (0) |
| 59 | extern unsigned long __udiv_qrnnd (unsigned int *, unsigned int, | 69 | extern unsigned long __udiv_qrnnd (unsigned int *, unsigned int, |
| 60 | unsigned int , unsigned int); | 70 | unsigned int , unsigned int); |
| 71 | #endif | ||
| 61 | 72 | ||
| 62 | #define UDIV_NEEDS_NORMALIZATION 0 | 73 | #define UDIV_NEEDS_NORMALIZATION 0 |
| 63 | 74 | ||
