aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-10 17:46:09 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-10 17:46:09 -0400
commit9f9d76321659b5ebc9939101481f7c3ce228ea6e (patch)
tree7abd21796ad85ba6c606cd2a93e787fb90b3abe6
parent1b21f458ddbc8fb6fceeb68158e9e04b2571dabd (diff)
parentf60d89108f3481ca11672b82cf7e67171e050ce4 (diff)
Merge branch 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.osdl.marist.edu/pub/scm/linux-2.6: [S390] vmlogrdr function annotation. [S390] s390: rename CPU_IDLE to S390_CPU_IDLE [S390] cio: Remove prototype for non-existing function cmf_reset(). [S390] zcrypt: fix request timeout handling [S390] system call optimization. [S390] dasd: Avoid compile warnings on !CONFIG_DASD_PROFILE [S390] Remove volatile from atomic_t [S390] Program check in diag 210 under 31 bit [S390] Bogomips calculation for 64 bit. [S390] smp: Merge smp_count_cpus() and smp_get_save_areas(). [S390] zcore: Fix __user annotation. [S390] fixed cdl-format detection. [S390] sclp: Test facility list before executing a service call. [S390] sclp: introduce some new interfaces. [S390] Fixed comment typo. [S390] vmcp cleanup
-rw-r--r--arch/s390/crypto/crypt_s390.h2
-rw-r--r--arch/s390/kernel/early.c45
-rw-r--r--arch/s390/kernel/entry.S7
-rw-r--r--arch/s390/kernel/entry64.S7
-rw-r--r--arch/s390/kernel/ipl.c17
-rw-r--r--arch/s390/kernel/process.c6
-rw-r--r--arch/s390/kernel/smp.c63
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/vtime.c4
-rw-r--r--arch/s390/lib/Makefile4
-rw-r--r--drivers/s390/block/dasd_proc.c4
-rw-r--r--drivers/s390/char/sclp.h12
-rw-r--r--drivers/s390/char/sclp_chp.c4
-rw-r--r--drivers/s390/char/sclp_info.c117
-rw-r--r--drivers/s390/char/vmcp.c13
-rw-r--r--drivers/s390/char/vmlogrdr.c4
-rw-r--r--drivers/s390/char/zcore.c2
-rw-r--r--drivers/s390/cio/device_id.c22
-rw-r--r--drivers/s390/crypto/ap_bus.c98
-rw-r--r--drivers/s390/crypto/ap_bus.h11
-rw-r--r--drivers/s390/crypto/zcrypt_cex2a.c27
-rw-r--r--drivers/s390/crypto/zcrypt_pcica.c27
-rw-r--r--drivers/s390/crypto/zcrypt_pcicc.c27
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c40
-rw-r--r--fs/partitions/ibm.c167
-rw-r--r--include/asm-s390/atomic.h4
-rw-r--r--include/asm-s390/cmb.h1
-rw-r--r--include/asm-s390/processor.h4
-rw-r--r--include/asm-s390/sclp.h47
-rw-r--r--include/asm-s390/sfp-machine.h6
-rw-r--r--include/asm-s390/sfp-util.h11
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 */
28enum crypt_s390_operations { 28enum 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
176static 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
205static inline __init unsigned long __tprot(unsigned long addr) 174static 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
222static noinline __init void find_memory_chunks(unsigned long memsize) 192static 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 */
294void __init startup_init(void) 264void __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
219sysc_saveall: 224sysc_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
208sysc_saveall: 213sysc_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
147static enum shutdown_action on_panic_action = SHUTDOWN_STOP; 143static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
148 144
145static struct sclp_ipl_info sclp_ipl_info;
146
149int diag308(unsigned long subcode, void *addr) 147int 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
100extern void s390_handle_mcck(void); 100extern 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);
410unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \ 410unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \
411 __attribute__((__section__(".data"))); 411 __attribute__((__section__(".data")));
412 412
413static void __init smp_get_save_areas(void) 413static 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
454union save_area *zfcpdump_save_areas[NR_CPUS + 1]; 435union save_area *zfcpdump_save_areas[NR_CPUS + 1];
455EXPORT_SYMBOL_GPL(zfcpdump_save_areas); 436EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
456 437
457#else 438#else
458#define smp_get_save_areas() do { } while (0) 439
459#endif 440static 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
465static unsigned int __init smp_count_cpus(void) 447static 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
5EXTRA_AFLAGS := -traditional 5EXTRA_AFLAGS := -traditional
6 6
7lib-y += delay.o string.o uaccess_std.o uaccess_pt.o qrnnd.o 7lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
8obj-$(CONFIG_32BIT) += div64.o 8obj-$(CONFIG_32BIT) += div64.o qrnnd.o
9lib-$(CONFIG_64BIT) += uaccess_mvcos.o 9lib-$(CONFIG_64BIT) += uaccess_mvcos.o
10lib-$(CONFIG_SMP) += spinlock.o 10lib-$(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;
28static struct proc_dir_entry *dasd_devices_entry = NULL; 28static struct proc_dir_entry *dasd_devices_entry = NULL;
29static struct proc_dir_entry *dasd_statistics_entry = NULL; 29static struct proc_dir_entry *dasd_statistics_entry = NULL;
30 30
31#ifdef CONFIG_DASD_PROFILE
31static char * 32static char *
32dasd_get_user_string(const char __user *user_buf, size_t user_len) 33dasd_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
51static int 53static int
52dasd_devices_show(struct seq_file *m, void *v) 54dasd_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
170static char * 173static char *
171dasd_statistics_array(char *str, unsigned int *array, int shift) 174dasd_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
184static int 188static int
185dasd_statistics_read(char *page, char **start, off_t off, 189dasd_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
73typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */ 73typedef u32 sccb_mask_t; /* ATTENTION: assumes 32bit mask !!! */
74 74
75struct sccb_header {
76 u16 length;
77 u8 function_code;
78 u8 control_mask[3];
79 u16 response_code;
80} __attribute__((packed));
81
82extern u64 sclp_facilities;
83
84#define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL)
85#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL)
86
75struct gds_subvector { 87struct 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
14struct sclp_readinfo_sccb s390_readinfo_sccb; 14struct 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
30static struct sclp_readinfo_sccb __initdata early_readinfo_sccb;
31static int __initdata early_readinfo_sccb_valid;
32
33u64 sclp_facilities;
15 34
16void __init sclp_readinfo_early(void) 35void __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; 75void __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) 82unsigned 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
55out: 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 */
105void __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
176static const struct file_operations vmcp_fops = { 176static 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
187static struct miscdevice vmcp_dev = { 186static 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
838static int vmlogrdr_init(void) 838static 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
888static void vmlogrdr_exit(void) 888static 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
159static int memcpy_real_user(__user void *dest, unsigned long src, size_t count) 159static 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
31int 30int
32diag210(struct diag210 * addr) 31diag210(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
62int
63diag210(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);
43static void ap_poll_timeout(unsigned long); 43static void ap_poll_timeout(unsigned long);
44static int ap_poll_thread_start(void); 44static int ap_poll_thread_start(void);
45static void ap_poll_thread_stop(void); 45static void ap_poll_thread_stop(void);
46static 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 */
351static 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 */
366static 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 */
346static ssize_t ap_hwtype_show(struct device *dev, 385static 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 */
1100static 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 */
1222static 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
1150static void ap_reset_domain(void) 1230static 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
86struct ap_device; 94struct ap_device;
87struct ap_message; 95struct 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 }
321out_free: 317out_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 }
363out_free: 354out_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 }
305out_free: 301out_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 }
347out_free: 338out_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 }
516out_free: 512out_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 }
559out_free: 550out_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 }
656out_free: 652out_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 }
700out_free: 691out_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 }
743out_free: 729out_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 &sect)) != 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 &sect);
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 &sect);
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 &sect);
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
26typedef struct { 26typedef 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__
143typedef struct { 143typedef 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 **/
90extern int cmf_readall(struct ccw_device *cdev, struct cmbdata*data); 90extern int cmf_readall(struct ccw_device *cdev, struct cmbdata*data);
91extern 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
363struct notifier_block; 363struct notifier_block;
364int register_idle_notifier(struct notifier_block *nb); 364int 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
14struct 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
23struct 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
39struct sclp_chp_info { 16struct 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
45extern struct sclp_readinfo_sccb s390_readinfo_sccb; 22#define LOADPARM_LEN 8
46extern void sclp_readinfo_early(void); 23
47extern int sclp_sdias_blk_count(void); 24struct sclp_ipl_info {
48extern int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); 25 int is_valid;
49extern int sclp_chp_configure(struct chp_id chpid); 26 int has_dump;
50extern int sclp_chp_deconfigure(struct chp_id chpid); 27 char loadparm[LOADPARM_LEN];
51extern int sclp_chp_read_info(struct sclp_chp_info *info); 28};
29
30void sclp_readinfo_early(void);
31void sclp_facilities_detect(void);
32unsigned long long sclp_memory_detect(void);
33int sclp_sdias_blk_count(void);
34int sclp_sdias_copy(void *dest, int blk_num, int nr_blks);
35int sclp_chp_configure(struct chp_id chpid);
36int sclp_chp_deconfigure(struct chp_id chpid);
37int sclp_chp_read_info(struct sclp_chp_info *info);
38void 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)
59extern unsigned long __udiv_qrnnd (unsigned int *, unsigned int, 69extern 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