aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/Kconfig4
-rw-r--r--arch/s390/Makefile12
-rw-r--r--arch/s390/defconfig21
-rw-r--r--arch/s390/kernel/early.c5
-rw-r--r--arch/s390/kernel/head31.S15
-rw-r--r--arch/s390/kernel/head64.S16
-rw-r--r--arch/s390/kernel/ipl.c33
-rw-r--r--arch/s390/kernel/setup.c10
-rw-r--r--arch/s390/kernel/smp.c182
-rw-r--r--arch/s390/kernel/time.c10
-rw-r--r--arch/s390/lib/delay.c7
-rw-r--r--arch/s390/mm/init.c2
-rw-r--r--drivers/s390/char/sclp_quiesce.c1
-rw-r--r--drivers/s390/cio/cio.c3
-rw-r--r--include/asm-s390/atomic.h2
-rw-r--r--include/asm-s390/ipl.h113
-rw-r--r--include/asm-s390/local.h59
-rw-r--r--include/asm-s390/processor.h5
-rw-r--r--include/asm-s390/sections.h2
-rw-r--r--include/asm-s390/setup.h74
20 files changed, 269 insertions, 307 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index eaaac3788110..d9425f59be91 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -8,8 +8,8 @@ config MMU
8 default y 8 default y
9 9
10config ZONE_DMA 10config ZONE_DMA
11 bool 11 def_bool y
12 default y 12 depends on 64BIT
13 13
14config LOCKDEP_SUPPORT 14config LOCKDEP_SUPPORT
15 bool 15 bool
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 6598e5268573..b1e558496469 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -82,18 +82,18 @@ AFLAGS += $(aflags-y)
82OBJCOPYFLAGS := -O binary 82OBJCOPYFLAGS := -O binary
83LDFLAGS_vmlinux := -e start 83LDFLAGS_vmlinux := -e start
84 84
85head-y := arch/$(ARCH)/kernel/head.o arch/$(ARCH)/kernel/init_task.o 85head-y := arch/s390/kernel/head.o arch/s390/kernel/init_task.o
86 86
87core-y += arch/$(ARCH)/mm/ arch/$(ARCH)/kernel/ arch/$(ARCH)/crypto/ \ 87core-y += arch/s390/mm/ arch/s390/kernel/ arch/s390/crypto/ \
88 arch/$(ARCH)/appldata/ arch/$(ARCH)/hypfs/ 88 arch/s390/appldata/ arch/s390/hypfs/
89libs-y += arch/$(ARCH)/lib/ 89libs-y += arch/s390/lib/
90drivers-y += drivers/s390/ 90drivers-y += drivers/s390/
91drivers-$(CONFIG_MATHEMU) += arch/$(ARCH)/math-emu/ 91drivers-$(CONFIG_MATHEMU) += arch/s390/math-emu/
92 92
93# must be linked after kernel 93# must be linked after kernel
94drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ 94drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/
95 95
96boot := arch/$(ARCH)/boot 96boot := arch/s390/boot
97 97
98all: image 98all: image
99 99
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 1406400bf3ea..741d2bbb2b37 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,9 +1,10 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20-rc1 3# Linux kernel version: 2.6.21-rc1
4# Fri Dec 15 16:52:28 2006 4# Wed Feb 21 10:44:30 2007
5# 5#
6CONFIG_MMU=y 6CONFIG_MMU=y
7CONFIG_ZONE_DMA=y
7CONFIG_LOCKDEP_SUPPORT=y 8CONFIG_LOCKDEP_SUPPORT=y
8CONFIG_STACKTRACE_SUPPORT=y 9CONFIG_STACKTRACE_SUPPORT=y
9CONFIG_RWSEM_XCHGADD_ALGORITHM=y 10CONFIG_RWSEM_XCHGADD_ALGORITHM=y
@@ -11,6 +12,7 @@ CONFIG_RWSEM_XCHGADD_ALGORITHM=y
11# CONFIG_ARCH_HAS_ILOG2_U64 is not set 12# CONFIG_ARCH_HAS_ILOG2_U64 is not set
12CONFIG_GENERIC_HWEIGHT=y 13CONFIG_GENERIC_HWEIGHT=y
13CONFIG_GENERIC_TIME=y 14CONFIG_GENERIC_TIME=y
15CONFIG_NO_IOMEM=y
14CONFIG_S390=y 16CONFIG_S390=y
15CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 17CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
16 18
@@ -29,6 +31,7 @@ CONFIG_LOCALVERSION_AUTO=y
29CONFIG_SWAP=y 31CONFIG_SWAP=y
30CONFIG_SYSVIPC=y 32CONFIG_SYSVIPC=y
31# CONFIG_IPC_NS is not set 33# CONFIG_IPC_NS is not set
34CONFIG_SYSVIPC_SYSCTL=y
32CONFIG_POSIX_MQUEUE=y 35CONFIG_POSIX_MQUEUE=y
33# CONFIG_BSD_PROCESS_ACCT is not set 36# CONFIG_BSD_PROCESS_ACCT is not set
34# CONFIG_TASKSTATS is not set 37# CONFIG_TASKSTATS is not set
@@ -133,6 +136,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
133# CONFIG_SPARSEMEM_STATIC is not set 136# CONFIG_SPARSEMEM_STATIC is not set
134CONFIG_SPLIT_PTLOCK_CPUS=4 137CONFIG_SPLIT_PTLOCK_CPUS=4
135CONFIG_RESOURCES_64BIT=y 138CONFIG_RESOURCES_64BIT=y
139CONFIG_ZONE_DMA_FLAG=1
136CONFIG_HOLES_IN_ZONE=y 140CONFIG_HOLES_IN_ZONE=y
137 141
138# 142#
@@ -178,7 +182,9 @@ CONFIG_UNIX=y
178CONFIG_XFRM=y 182CONFIG_XFRM=y
179# CONFIG_XFRM_USER is not set 183# CONFIG_XFRM_USER is not set
180# CONFIG_XFRM_SUB_POLICY is not set 184# CONFIG_XFRM_SUB_POLICY is not set
185# CONFIG_XFRM_MIGRATE is not set
181CONFIG_NET_KEY=y 186CONFIG_NET_KEY=y
187# CONFIG_NET_KEY_MIGRATE is not set
182CONFIG_IUCV=m 188CONFIG_IUCV=m
183CONFIG_AFIUCV=m 189CONFIG_AFIUCV=m
184CONFIG_INET=y 190CONFIG_INET=y
@@ -195,7 +201,7 @@ CONFIG_IP_FIB_HASH=y
195# CONFIG_INET_ESP is not set 201# CONFIG_INET_ESP is not set
196# CONFIG_INET_IPCOMP is not set 202# CONFIG_INET_IPCOMP is not set
197# CONFIG_INET_XFRM_TUNNEL is not set 203# CONFIG_INET_XFRM_TUNNEL is not set
198# CONFIG_INET_TUNNEL is not set 204CONFIG_INET_TUNNEL=y
199CONFIG_INET_XFRM_MODE_TRANSPORT=y 205CONFIG_INET_XFRM_MODE_TRANSPORT=y
200CONFIG_INET_XFRM_MODE_TUNNEL=y 206CONFIG_INET_XFRM_MODE_TUNNEL=y
201CONFIG_INET_XFRM_MODE_BEET=y 207CONFIG_INET_XFRM_MODE_BEET=y
@@ -313,6 +319,7 @@ CONFIG_STANDALONE=y
313CONFIG_PREVENT_FIRMWARE_BUILD=y 319CONFIG_PREVENT_FIRMWARE_BUILD=y
314# CONFIG_FW_LOADER is not set 320# CONFIG_FW_LOADER is not set
315# CONFIG_DEBUG_DRIVER is not set 321# CONFIG_DEBUG_DRIVER is not set
322# CONFIG_DEBUG_DEVRES is not set
316CONFIG_SYS_HYPERVISOR=y 323CONFIG_SYS_HYPERVISOR=y
317 324
318# 325#
@@ -686,13 +693,13 @@ CONFIG_HEADERS_CHECK=y
686CONFIG_DEBUG_KERNEL=y 693CONFIG_DEBUG_KERNEL=y
687CONFIG_LOG_BUF_SHIFT=17 694CONFIG_LOG_BUF_SHIFT=17
688# CONFIG_SCHEDSTATS is not set 695# CONFIG_SCHEDSTATS is not set
696# CONFIG_TIMER_STATS is not set
689# CONFIG_DEBUG_SLAB is not set 697# CONFIG_DEBUG_SLAB is not set
690CONFIG_DEBUG_PREEMPT=y 698CONFIG_DEBUG_PREEMPT=y
691# CONFIG_DEBUG_RT_MUTEXES is not set 699# CONFIG_DEBUG_RT_MUTEXES is not set
692# CONFIG_RT_MUTEX_TESTER is not set 700# CONFIG_RT_MUTEX_TESTER is not set
693CONFIG_DEBUG_SPINLOCK=y 701CONFIG_DEBUG_SPINLOCK=y
694CONFIG_DEBUG_MUTEXES=y 702CONFIG_DEBUG_MUTEXES=y
695# CONFIG_DEBUG_RWSEMS is not set
696# CONFIG_DEBUG_LOCK_ALLOC is not set 703# CONFIG_DEBUG_LOCK_ALLOC is not set
697# CONFIG_PROVE_LOCKING is not set 704# CONFIG_PROVE_LOCKING is not set
698CONFIG_DEBUG_SPINLOCK_SLEEP=y 705CONFIG_DEBUG_SPINLOCK_SLEEP=y
@@ -702,10 +709,10 @@ CONFIG_DEBUG_SPINLOCK_SLEEP=y
702# CONFIG_DEBUG_VM is not set 709# CONFIG_DEBUG_VM is not set
703# CONFIG_DEBUG_LIST is not set 710# CONFIG_DEBUG_LIST is not set
704# CONFIG_FRAME_POINTER is not set 711# CONFIG_FRAME_POINTER is not set
705# CONFIG_UNWIND_INFO is not set
706CONFIG_FORCED_INLINING=y 712CONFIG_FORCED_INLINING=y
707# CONFIG_RCU_TORTURE_TEST is not set 713# CONFIG_RCU_TORTURE_TEST is not set
708# CONFIG_LKDTM is not set 714# CONFIG_LKDTM is not set
715# CONFIG_FAULT_INJECTION is not set
709 716
710# 717#
711# Security options 718# Security options
@@ -733,8 +740,10 @@ CONFIG_CRYPTO_MANAGER=y
733# CONFIG_CRYPTO_GF128MUL is not set 740# CONFIG_CRYPTO_GF128MUL is not set
734CONFIG_CRYPTO_ECB=m 741CONFIG_CRYPTO_ECB=m
735CONFIG_CRYPTO_CBC=y 742CONFIG_CRYPTO_CBC=y
743CONFIG_CRYPTO_PCBC=m
736# CONFIG_CRYPTO_LRW is not set 744# CONFIG_CRYPTO_LRW is not set
737# CONFIG_CRYPTO_DES is not set 745# CONFIG_CRYPTO_DES is not set
746CONFIG_CRYPTO_FCRYPT=m
738# CONFIG_CRYPTO_BLOWFISH is not set 747# CONFIG_CRYPTO_BLOWFISH is not set
739# CONFIG_CRYPTO_TWOFISH is not set 748# CONFIG_CRYPTO_TWOFISH is not set
740# CONFIG_CRYPTO_SERPENT is not set 749# CONFIG_CRYPTO_SERPENT is not set
@@ -748,6 +757,7 @@ CONFIG_CRYPTO_CBC=y
748# CONFIG_CRYPTO_DEFLATE is not set 757# CONFIG_CRYPTO_DEFLATE is not set
749# CONFIG_CRYPTO_MICHAEL_MIC is not set 758# CONFIG_CRYPTO_MICHAEL_MIC is not set
750# CONFIG_CRYPTO_CRC32C is not set 759# CONFIG_CRYPTO_CRC32C is not set
760CONFIG_CRYPTO_CAMELLIA=m
751# CONFIG_CRYPTO_TEST is not set 761# CONFIG_CRYPTO_TEST is not set
752 762
753# 763#
@@ -768,4 +778,3 @@ CONFIG_BITREVERSE=m
768CONFIG_CRC32=m 778CONFIG_CRC32=m
769# CONFIG_LIBCRC32C is not set 779# CONFIG_LIBCRC32C is not set
770CONFIG_PLIST=y 780CONFIG_PLIST=y
771CONFIG_IOMAP_COPY=y
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index e518dd53eff5..afca1c6f4d21 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/pfn.h> 15#include <linux/pfn.h>
16#include <linux/uaccess.h> 16#include <linux/uaccess.h>
17#include <asm/ipl.h>
17#include <asm/lowcore.h> 18#include <asm/lowcore.h>
18#include <asm/processor.h> 19#include <asm/processor.h>
19#include <asm/sections.h> 20#include <asm/sections.h>
@@ -109,7 +110,7 @@ static inline void create_kernel_nss(void) { }
109 */ 110 */
110static noinline __init void clear_bss_section(void) 111static noinline __init void clear_bss_section(void)
111{ 112{
112 memset(__bss_start, 0, _end - __bss_start); 113 memset(__bss_start, 0, __bss_stop - __bss_start);
113} 114}
114 115
115/* 116/*
@@ -129,7 +130,7 @@ static noinline __init void detect_machine_type(void)
129{ 130{
130 struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data; 131 struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data;
131 132
132 asm volatile("stidp %0" : "=m" (S390_lowcore.cpu_data.cpu_id)); 133 get_cpu_id(&S390_lowcore.cpu_data.cpu_id);
133 134
134 /* Running under z/VM ? */ 135 /* Running under z/VM ? */
135 if (cpuinfo->cpu_id.version == 0xff) 136 if (cpuinfo->cpu_id.version == 0xff)
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index 453fd3b4edea..da7c8bb80982 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -148,20 +148,9 @@ startup_continue:
148.Lstartup_init: 148.Lstartup_init:
149 .long startup_init 149 .long startup_init
150 150
151 .globl ipl_schib
152ipl_schib:
153 .rept 13
154 .long 0
155 .endr
156
157 .globl ipl_flags
158ipl_flags:
159 .long 0
160 .globl ipl_devno
161ipl_devno:
162 .word 0
163
164 .org 0x12000 151 .org 0x12000
152 .globl _ehead
153_ehead:
165#ifdef CONFIG_SHARED_KERNEL 154#ifdef CONFIG_SHARED_KERNEL
166 .org 0x100000 155 .org 0x100000
167#endif 156#endif
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index b8fec4e5c5d4..af09e18cc5d0 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -154,21 +154,9 @@ startup_continue:
154.Lparmaddr: 154.Lparmaddr:
155 .quad PARMAREA 155 .quad PARMAREA
156 156
157 .globl ipl_schib
158ipl_schib:
159 .rept 13
160 .long 0
161 .endr
162
163 .globl ipl_flags
164ipl_flags:
165 .long 0
166 .globl ipl_devno
167ipl_devno:
168 .word 0
169
170 .org 0x12000 157 .org 0x12000
171 158 .globl _ehead
159_ehead:
172#ifdef CONFIG_SHARED_KERNEL 160#ifdef CONFIG_SHARED_KERNEL
173 .org 0x100000 161 .org 0x100000
174#endif 162#endif
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 052259530651..5a863a3bf10c 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -14,6 +14,7 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/reboot.h> 15#include <linux/reboot.h>
16#include <linux/ctype.h> 16#include <linux/ctype.h>
17#include <asm/ipl.h>
17#include <asm/smp.h> 18#include <asm/smp.h>
18#include <asm/setup.h> 19#include <asm/setup.h>
19#include <asm/cpcmd.h> 20#include <asm/cpcmd.h>
@@ -42,6 +43,13 @@ enum ipl_type {
42#define IPL_FCP_STR "fcp" 43#define IPL_FCP_STR "fcp"
43#define IPL_NSS_STR "nss" 44#define IPL_NSS_STR "nss"
44 45
46/*
47 * Must be in data section since the bss section
48 * is not cleared when these are accessed.
49 */
50u16 ipl_devno __attribute__((__section__(".data"))) = 0;
51u32 ipl_flags __attribute__((__section__(".data"))) = 0;
52
45static char *ipl_type_str(enum ipl_type type) 53static char *ipl_type_str(enum ipl_type type)
46{ 54{
47 switch (type) { 55 switch (type) {
@@ -90,31 +98,10 @@ static char *shutdown_action_str(enum shutdown_action action)
90 case SHUTDOWN_STOP: 98 case SHUTDOWN_STOP:
91 return SHUTDOWN_STOP_STR; 99 return SHUTDOWN_STOP_STR;
92 default: 100 default:
93 BUG(); 101 return NULL;
94 } 102 }
95} 103}
96 104
97enum diag308_subcode {
98 DIAG308_IPL = 3,
99 DIAG308_DUMP = 4,
100 DIAG308_SET = 5,
101 DIAG308_STORE = 6,
102};
103
104enum diag308_ipl_type {
105 DIAG308_IPL_TYPE_FCP = 0,
106 DIAG308_IPL_TYPE_CCW = 2,
107};
108
109enum diag308_opt {
110 DIAG308_IPL_OPT_IPL = 0x10,
111 DIAG308_IPL_OPT_DUMP = 0x20,
112};
113
114enum diag308_rc {
115 DIAG308_RC_OK = 1,
116};
117
118static int diag308_set_works = 0; 105static int diag308_set_works = 0;
119 106
120static int reipl_capabilities = IPL_TYPE_UNKNOWN; 107static int reipl_capabilities = IPL_TYPE_UNKNOWN;
@@ -134,7 +121,7 @@ static struct ipl_parameter_block *dump_block_ccw;
134 121
135static enum shutdown_action on_panic_action = SHUTDOWN_STOP; 122static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
136 123
137static int diag308(unsigned long subcode, void *addr) 124int diag308(unsigned long subcode, void *addr)
138{ 125{
139 register unsigned long _addr asm("0") = (unsigned long) addr; 126 register unsigned long _addr asm("0") = (unsigned long) addr;
140 register unsigned long _rc asm("1") = 0; 127 register unsigned long _rc asm("1") = 0;
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 50c5210fbc64..863c8d08c026 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -41,6 +41,7 @@
41#include <linux/ctype.h> 41#include <linux/ctype.h>
42#include <linux/reboot.h> 42#include <linux/reboot.h>
43 43
44#include <asm/ipl.h>
44#include <asm/uaccess.h> 45#include <asm/uaccess.h>
45#include <asm/system.h> 46#include <asm/system.h>
46#include <asm/smp.h> 47#include <asm/smp.h>
@@ -106,7 +107,7 @@ void __devinit cpu_init (void)
106 /* 107 /*
107 * Store processor id in lowcore (used e.g. in timer_interrupt) 108 * Store processor id in lowcore (used e.g. in timer_interrupt)
108 */ 109 */
109 asm volatile("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id)); 110 get_cpu_id(&S390_lowcore.cpu_data.cpu_id);
110 S390_lowcore.cpu_data.cpu_addr = addr; 111 S390_lowcore.cpu_data.cpu_addr = addr;
111 112
112 /* 113 /*
@@ -689,9 +690,14 @@ setup_memory(void)
689 psw_set_key(PAGE_DEFAULT_KEY); 690 psw_set_key(PAGE_DEFAULT_KEY);
690 691
691 free_bootmem_with_active_regions(0, max_pfn); 692 free_bootmem_with_active_regions(0, max_pfn);
692 reserve_bootmem(0, PFN_PHYS(start_pfn));
693 693
694 /* 694 /*
695 * Reserve memory used for lowcore/command line/kernel image.
696 */
697 reserve_bootmem(0, (unsigned long)_ehead);
698 reserve_bootmem((unsigned long)_stext,
699 PFN_PHYS(start_pfn) - (unsigned long)_stext);
700 /*
695 * Reserve the bootmem bitmap itself as well. We do this in two 701 * Reserve the bootmem bitmap itself as well. We do this in two
696 * steps (first step was init_bootmem()) because this catches 702 * steps (first step was init_bootmem()) because this catches
697 * the (very unlikely) case of us accidentally initializing the 703 * the (very unlikely) case of us accidentally initializing the
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 83a4ea6e3d60..ecaa432a99f8 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -31,6 +31,7 @@
31#include <linux/interrupt.h> 31#include <linux/interrupt.h>
32#include <linux/cpu.h> 32#include <linux/cpu.h>
33#include <linux/timex.h> 33#include <linux/timex.h>
34#include <asm/ipl.h>
34#include <asm/setup.h> 35#include <asm/setup.h>
35#include <asm/sigp.h> 36#include <asm/sigp.h>
36#include <asm/pgalloc.h> 37#include <asm/pgalloc.h>
@@ -54,19 +55,18 @@ cpumask_t cpu_possible_map = CPU_MASK_NONE;
54static struct task_struct *current_set[NR_CPUS]; 55static struct task_struct *current_set[NR_CPUS];
55 56
56static void smp_ext_bitcall(int, ec_bit_sig); 57static void smp_ext_bitcall(int, ec_bit_sig);
57static void smp_ext_bitcall_others(ec_bit_sig);
58 58
59/* 59/*
60 * Structure and data for smp_call_function(). This is designed to minimise 60 * Structure and data for __smp_call_function_map(). This is designed to
61 * static memory requirements. It also looks cleaner. 61 * minimise static memory requirements. It also looks cleaner.
62 */ 62 */
63static DEFINE_SPINLOCK(call_lock); 63static DEFINE_SPINLOCK(call_lock);
64 64
65struct call_data_struct { 65struct call_data_struct {
66 void (*func) (void *info); 66 void (*func) (void *info);
67 void *info; 67 void *info;
68 atomic_t started; 68 cpumask_t started;
69 atomic_t finished; 69 cpumask_t finished;
70 int wait; 70 int wait;
71}; 71};
72 72
@@ -81,118 +81,113 @@ static void do_call_function(void)
81 void *info = call_data->info; 81 void *info = call_data->info;
82 int wait = call_data->wait; 82 int wait = call_data->wait;
83 83
84 atomic_inc(&call_data->started); 84 cpu_set(smp_processor_id(), call_data->started);
85 (*func)(info); 85 (*func)(info);
86 if (wait) 86 if (wait)
87 atomic_inc(&call_data->finished); 87 cpu_set(smp_processor_id(), call_data->finished);;
88} 88}
89 89
90/* 90static void __smp_call_function_map(void (*func) (void *info), void *info,
91 * this function sends a 'generic call function' IPI to all other CPUs 91 int nonatomic, int wait, cpumask_t map)
92 * in the system.
93 */
94
95int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
96 int wait)
97/*
98 * [SUMMARY] Run a function on all other CPUs.
99 * <func> The function to run. This must be fast and non-blocking.
100 * <info> An arbitrary pointer to pass to the function.
101 * <nonatomic> currently unused.
102 * <wait> If true, wait (atomically) until function has completed on other CPUs.
103 * [RETURNS] 0 on success, else a negative status code. Does not return until
104 * remote CPUs are nearly ready to execute <<func>> or are or have executed.
105 *
106 * You must not call this function with disabled interrupts or from a
107 * hardware interrupt handler.
108 */
109{ 92{
110 struct call_data_struct data; 93 struct call_data_struct data;
111 int cpus = num_online_cpus()-1; 94 int cpu, local = 0;
112 95
113 if (cpus <= 0) 96 /*
114 return 0; 97 * Can deadlock when interrupts are disabled or if in wrong context,
98 * caller must disable preemption
99 */
100 WARN_ON(irqs_disabled() || in_irq() || preemptible());
115 101
116 /* Can deadlock when interrupts are disabled or if in wrong context */ 102 /*
117 WARN_ON(irqs_disabled() || in_irq()); 103 * Check for local function call. We have to have the same call order
104 * as in on_each_cpu() because of machine_restart_smp().
105 */
106 if (cpu_isset(smp_processor_id(), map)) {
107 local = 1;
108 cpu_clear(smp_processor_id(), map);
109 }
110
111 cpus_and(map, map, cpu_online_map);
112 if (cpus_empty(map))
113 goto out;
118 114
119 data.func = func; 115 data.func = func;
120 data.info = info; 116 data.info = info;
121 atomic_set(&data.started, 0); 117 data.started = CPU_MASK_NONE;
122 data.wait = wait; 118 data.wait = wait;
123 if (wait) 119 if (wait)
124 atomic_set(&data.finished, 0); 120 data.finished = CPU_MASK_NONE;
125 121
126 spin_lock_bh(&call_lock); 122 spin_lock_bh(&call_lock);
127 call_data = &data; 123 call_data = &data;
128 /* Send a message to all other CPUs and wait for them to respond */ 124
129 smp_ext_bitcall_others(ec_call_function); 125 for_each_cpu_mask(cpu, map)
126 smp_ext_bitcall(cpu, ec_call_function);
130 127
131 /* Wait for response */ 128 /* Wait for response */
132 while (atomic_read(&data.started) != cpus) 129 while (!cpus_equal(map, data.started))
133 cpu_relax(); 130 cpu_relax();
134 131
135 if (wait) 132 if (wait)
136 while (atomic_read(&data.finished) != cpus) 133 while (!cpus_equal(map, data.finished))
137 cpu_relax(); 134 cpu_relax();
135
138 spin_unlock_bh(&call_lock); 136 spin_unlock_bh(&call_lock);
139 137
140 return 0; 138out:
139 local_irq_disable();
140 if (local)
141 func(info);
142 local_irq_enable();
141} 143}
142 144
143/* 145/*
144 * Call a function on one CPU 146 * smp_call_function:
145 * cpu : the CPU the function should be executed on 147 * @func: the function to run; this must be fast and non-blocking
148 * @info: an arbitrary pointer to pass to the function
149 * @nonatomic: unused
150 * @wait: if true, wait (atomically) until function has completed on other CPUs
146 * 151 *
147 * You must not call this function with disabled interrupts or from a 152 * Run a function on all other CPUs.
148 * hardware interrupt handler. You may call it from a bottom half.
149 * 153 *
150 * It is guaranteed that the called function runs on the specified CPU, 154 * You must not call this function with disabled interrupts or from a
151 * preemption is disabled. 155 * hardware interrupt handler. Must be called with preemption disabled.
156 * You may call it from a bottom half.
152 */ 157 */
153int smp_call_function_on(void (*func) (void *info), void *info, 158int smp_call_function(void (*func) (void *info), void *info, int nonatomic,
154 int nonatomic, int wait, int cpu) 159 int wait)
155{ 160{
156 struct call_data_struct data; 161 cpumask_t map;
157 int curr_cpu;
158
159 if (!cpu_online(cpu))
160 return -EINVAL;
161
162 /* Can deadlock when interrupts are disabled or if in wrong context */
163 WARN_ON(irqs_disabled() || in_irq());
164
165 /* disable preemption for local function call */
166 curr_cpu = get_cpu();
167
168 if (curr_cpu == cpu) {
169 /* direct call to function */
170 func(info);
171 put_cpu();
172 return 0;
173 }
174
175 data.func = func;
176 data.info = info;
177 atomic_set(&data.started, 0);
178 data.wait = wait;
179 if (wait)
180 atomic_set(&data.finished, 0);
181
182 spin_lock_bh(&call_lock);
183 call_data = &data;
184 smp_ext_bitcall(cpu, ec_call_function);
185 162
186 /* Wait for response */ 163 map = cpu_online_map;
187 while (atomic_read(&data.started) != 1) 164 cpu_clear(smp_processor_id(), map);
188 cpu_relax(); 165 __smp_call_function_map(func, info, nonatomic, wait, map);
166 return 0;
167}
168EXPORT_SYMBOL(smp_call_function);
189 169
190 if (wait) 170/*
191 while (atomic_read(&data.finished) != 1) 171 * smp_call_function_on:
192 cpu_relax(); 172 * @func: the function to run; this must be fast and non-blocking
173 * @info: an arbitrary pointer to pass to the function
174 * @nonatomic: unused
175 * @wait: if true, wait (atomically) until function has completed on other CPUs
176 * @cpu: the CPU where func should run
177 *
178 * Run a function on one processor.
179 *
180 * You must not call this function with disabled interrupts or from a
181 * hardware interrupt handler. Must be called with preemption disabled.
182 * You may call it from a bottom half.
183 */
184int smp_call_function_on(void (*func) (void *info), void *info, int nonatomic,
185 int wait, int cpu)
186{
187 cpumask_t map = CPU_MASK_NONE;
193 188
194 spin_unlock_bh(&call_lock); 189 cpu_set(cpu, map);
195 put_cpu(); 190 __smp_call_function_map(func, info, nonatomic, wait, map);
196 return 0; 191 return 0;
197} 192}
198EXPORT_SYMBOL(smp_call_function_on); 193EXPORT_SYMBOL(smp_call_function_on);
@@ -325,26 +320,6 @@ static void smp_ext_bitcall(int cpu, ec_bit_sig sig)
325 udelay(10); 320 udelay(10);
326} 321}
327 322
328/*
329 * Send an external call sigp to every other cpu in the system and
330 * return without waiting for its completion.
331 */
332static void smp_ext_bitcall_others(ec_bit_sig sig)
333{
334 int cpu;
335
336 for_each_online_cpu(cpu) {
337 if (cpu == smp_processor_id())
338 continue;
339 /*
340 * Set signaling bit in lowcore of target cpu and kick it
341 */
342 set_bit(sig, (unsigned long *) &lowcore_ptr[cpu]->ext_call_fast);
343 while (signal_processor(cpu, sigp_emergency_signal) == sigp_busy)
344 udelay(10);
345 }
346}
347
348#ifndef CONFIG_64BIT 323#ifndef CONFIG_64BIT
349/* 324/*
350 * this function sends a 'purge tlb' signal to another CPU. 325 * this function sends a 'purge tlb' signal to another CPU.
@@ -807,6 +782,5 @@ EXPORT_SYMBOL(cpu_possible_map);
807EXPORT_SYMBOL(lowcore_ptr); 782EXPORT_SYMBOL(lowcore_ptr);
808EXPORT_SYMBOL(smp_ctl_set_bit); 783EXPORT_SYMBOL(smp_ctl_set_bit);
809EXPORT_SYMBOL(smp_ctl_clear_bit); 784EXPORT_SYMBOL(smp_ctl_clear_bit);
810EXPORT_SYMBOL(smp_call_function);
811EXPORT_SYMBOL(smp_get_cpu); 785EXPORT_SYMBOL(smp_get_cpu);
812EXPORT_SYMBOL(smp_put_cpu); 786EXPORT_SYMBOL(smp_put_cpu);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index ee9fd7b85928..e1ad464b6f20 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -747,6 +747,7 @@ static void etr_adjust_time(unsigned long long clock, unsigned long long delay)
747 } 747 }
748} 748}
749 749
750#ifdef CONFIG_SMP
750static void etr_sync_cpu_start(void *dummy) 751static void etr_sync_cpu_start(void *dummy)
751{ 752{
752 int *in_sync = dummy; 753 int *in_sync = dummy;
@@ -758,8 +759,14 @@ static void etr_sync_cpu_start(void *dummy)
758 * __udelay will stop the cpu on an enabled wait psw until the 759 * __udelay will stop the cpu on an enabled wait psw until the
759 * TOD is running again. 760 * TOD is running again.
760 */ 761 */
761 while (*in_sync == 0) 762 while (*in_sync == 0) {
762 __udelay(1); 763 __udelay(1);
764 /*
765 * A different cpu changes *in_sync. Therefore use
766 * barrier() to force memory access.
767 */
768 barrier();
769 }
763 if (*in_sync != 1) 770 if (*in_sync != 1)
764 /* Didn't work. Clear per-cpu in sync bit again. */ 771 /* Didn't work. Clear per-cpu in sync bit again. */
765 etr_disable_sync_clock(NULL); 772 etr_disable_sync_clock(NULL);
@@ -773,6 +780,7 @@ static void etr_sync_cpu_start(void *dummy)
773static void etr_sync_cpu_end(void *dummy) 780static void etr_sync_cpu_end(void *dummy)
774{ 781{
775} 782}
783#endif /* CONFIG_SMP */
776 784
777/* 785/*
778 * Sync the TOD clock using the port refered to by aibp. This port 786 * Sync the TOD clock using the port refered to by aibp. This port
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index 02854449b74b..70f2a862b670 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -15,6 +15,7 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/timex.h> 16#include <linux/timex.h>
17#include <linux/irqflags.h> 17#include <linux/irqflags.h>
18#include <linux/interrupt.h>
18 19
19void __delay(unsigned long loops) 20void __delay(unsigned long loops)
20{ 21{
@@ -35,7 +36,11 @@ void __udelay(unsigned long usecs)
35{ 36{
36 u64 end, time, jiffy_timer = 0; 37 u64 end, time, jiffy_timer = 0;
37 unsigned long flags, cr0, mask, dummy; 38 unsigned long flags, cr0, mask, dummy;
39 int irq_context;
38 40
41 irq_context = in_interrupt();
42 if (!irq_context)
43 local_bh_disable();
39 local_irq_save(flags); 44 local_irq_save(flags);
40 if (raw_irqs_disabled_flags(flags)) { 45 if (raw_irqs_disabled_flags(flags)) {
41 jiffy_timer = S390_lowcore.jiffy_timer; 46 jiffy_timer = S390_lowcore.jiffy_timer;
@@ -62,6 +67,8 @@ void __udelay(unsigned long usecs)
62 __ctl_load(cr0, 0, 0); 67 __ctl_load(cr0, 0, 0);
63 S390_lowcore.jiffy_timer = jiffy_timer; 68 S390_lowcore.jiffy_timer = jiffy_timer;
64 } 69 }
70 if (!irq_context)
71 _local_bh_enable();
65 set_clock_comparator(S390_lowcore.jiffy_timer); 72 set_clock_comparator(S390_lowcore.jiffy_timer);
66 local_irq_restore(flags); 73 local_irq_restore(flags);
67} 74}
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index b3e7c45efb63..916b72a8cde8 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -141,7 +141,9 @@ void __init paging_init(void)
141 __raw_local_irq_ssm(ssm_mask); 141 __raw_local_irq_ssm(ssm_mask);
142 142
143 memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); 143 memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
144#ifdef CONFIG_ZONE_DMA
144 max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS); 145 max_zone_pfns[ZONE_DMA] = PFN_DOWN(MAX_DMA_ADDRESS);
146#endif
145 max_zone_pfns[ZONE_NORMAL] = max_low_pfn; 147 max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
146 free_area_init_nodes(max_zone_pfns); 148 free_area_init_nodes(max_zone_pfns);
147} 149}
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c
index ffa9282ce97a..baa8fe669ed2 100644
--- a/drivers/s390/char/sclp_quiesce.c
+++ b/drivers/s390/char/sclp_quiesce.c
@@ -16,6 +16,7 @@
16#include <asm/atomic.h> 16#include <asm/atomic.h>
17#include <asm/ptrace.h> 17#include <asm/ptrace.h>
18#include <asm/sigp.h> 18#include <asm/sigp.h>
19#include <asm/smp.h>
19 20
20#include "sclp.h" 21#include "sclp.h"
21 22
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index b3a56dc5f68a..9cb129ab5be5 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -21,6 +21,7 @@
21#include <asm/irq_regs.h> 21#include <asm/irq_regs.h>
22#include <asm/setup.h> 22#include <asm/setup.h>
23#include <asm/reset.h> 23#include <asm/reset.h>
24#include <asm/ipl.h>
24#include "airq.h" 25#include "airq.h"
25#include "cio.h" 26#include "cio.h"
26#include "css.h" 27#include "css.h"
@@ -1047,7 +1048,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
1047 do_reipl_asm(*((__u32*)&schid)); 1048 do_reipl_asm(*((__u32*)&schid));
1048} 1049}
1049 1050
1050extern struct schib ipl_schib; 1051static struct schib __initdata ipl_schib;
1051 1052
1052/* 1053/*
1053 * ipl_save_parameters gets called very early. It is not allowed to access 1054 * ipl_save_parameters gets called very early. It is not allowed to access
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h
index af20c7462485..c17bdbf22067 100644
--- a/include/asm-s390/atomic.h
+++ b/include/asm-s390/atomic.h
@@ -215,6 +215,8 @@ static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v)
215 __CSG_LOOP(v, mask, "ogr"); 215 __CSG_LOOP(v, mask, "ogr");
216} 216}
217 217
218#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
219
218static __inline__ long long atomic64_cmpxchg(atomic64_t *v, 220static __inline__ long long atomic64_cmpxchg(atomic64_t *v,
219 long long old, long long new) 221 long long old, long long new)
220{ 222{
diff --git a/include/asm-s390/ipl.h b/include/asm-s390/ipl.h
new file mode 100644
index 000000000000..5650d3d4ae46
--- /dev/null
+++ b/include/asm-s390/ipl.h
@@ -0,0 +1,113 @@
1/*
2 * s390 (re)ipl support
3 *
4 * Copyright IBM Corp. 2007
5 */
6
7#ifndef _ASM_S390_IPL_H
8#define _ASM_S390_IPL_H
9
10#include <asm/types.h>
11
12#define IPL_PARMBLOCK_ORIGIN 0x2000
13
14#define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \
15 sizeof(struct ipl_block_fcp))
16
17#define IPL_PARM_BLK_CCW_LEN (sizeof(struct ipl_list_hdr) + \
18 sizeof(struct ipl_block_ccw))
19
20#define IPL_MAX_SUPPORTED_VERSION (0)
21
22#define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \
23 IPL_PARMBLOCK_ORIGIN)
24#define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.len)
25
26struct ipl_list_hdr {
27 u32 len;
28 u8 reserved1[3];
29 u8 version;
30 u32 blk0_len;
31 u8 pbt;
32 u8 flags;
33 u16 reserved2;
34} __attribute__((packed));
35
36struct ipl_block_fcp {
37 u8 reserved1[313-1];
38 u8 opt;
39 u8 reserved2[3];
40 u16 reserved3;
41 u16 devno;
42 u8 reserved4[4];
43 u64 wwpn;
44 u64 lun;
45 u32 bootprog;
46 u8 reserved5[12];
47 u64 br_lba;
48 u32 scp_data_len;
49 u8 reserved6[260];
50 u8 scp_data[];
51} __attribute__((packed));
52
53struct ipl_block_ccw {
54 u8 load_param[8];
55 u8 reserved1[84];
56 u8 reserved2[2];
57 u16 devno;
58 u8 vm_flags;
59 u8 reserved3[3];
60 u32 vm_parm_len;
61} __attribute__((packed));
62
63struct ipl_parameter_block {
64 struct ipl_list_hdr hdr;
65 union {
66 struct ipl_block_fcp fcp;
67 struct ipl_block_ccw ccw;
68 } ipl_info;
69} __attribute__((packed));
70
71/*
72 * IPL validity flags and parameters as detected in head.S
73 */
74extern u32 ipl_flags;
75extern u16 ipl_devno;
76
77extern void do_reipl(void);
78extern void ipl_save_parameters(void);
79
80enum {
81 IPL_DEVNO_VALID = 1,
82 IPL_PARMBLOCK_VALID = 2,
83 IPL_NSS_VALID = 4,
84};
85
86/*
87 * DIAG 308 support
88 */
89enum diag308_subcode {
90 DIAG308_REL_HSA = 2,
91 DIAG308_IPL = 3,
92 DIAG308_DUMP = 4,
93 DIAG308_SET = 5,
94 DIAG308_STORE = 6,
95};
96
97enum diag308_ipl_type {
98 DIAG308_IPL_TYPE_FCP = 0,
99 DIAG308_IPL_TYPE_CCW = 2,
100};
101
102enum diag308_opt {
103 DIAG308_IPL_OPT_IPL = 0x10,
104 DIAG308_IPL_OPT_DUMP = 0x20,
105};
106
107enum diag308_rc {
108 DIAG308_RC_OK = 1,
109};
110
111extern int diag308(unsigned long subcode, void *addr);
112
113#endif /* _ASM_S390_IPL_H */
diff --git a/include/asm-s390/local.h b/include/asm-s390/local.h
index 86745a1b29bb..c11c530f74d0 100644
--- a/include/asm-s390/local.h
+++ b/include/asm-s390/local.h
@@ -1,58 +1 @@
1#ifndef _ASM_LOCAL_H #include <asm-generic/local.h>
2#define _ASM_LOCAL_H
3
4#include <linux/percpu.h>
5#include <asm/atomic.h>
6
7#ifndef __s390x__
8
9typedef atomic_t local_t;
10
11#define LOCAL_INIT(i) ATOMIC_INIT(i)
12#define local_read(v) atomic_read(v)
13#define local_set(v,i) atomic_set(v,i)
14
15#define local_inc(v) atomic_inc(v)
16#define local_dec(v) atomic_dec(v)
17#define local_add(i, v) atomic_add(i, v)
18#define local_sub(i, v) atomic_sub(i, v)
19
20#else
21
22typedef atomic64_t local_t;
23
24#define LOCAL_INIT(i) ATOMIC64_INIT(i)
25#define local_read(v) atomic64_read(v)
26#define local_set(v,i) atomic64_set(v,i)
27
28#define local_inc(v) atomic64_inc(v)
29#define local_dec(v) atomic64_dec(v)
30#define local_add(i, v) atomic64_add(i, v)
31#define local_sub(i, v) atomic64_sub(i, v)
32
33#endif
34
35#define __local_inc(v) ((v)->counter++)
36#define __local_dec(v) ((v)->counter--)
37#define __local_add(i,v) ((v)->counter+=(i))
38#define __local_sub(i,v) ((v)->counter-=(i))
39
40/*
41 * Use these for per-cpu local_t variables: on some archs they are
42 * much more efficient than these naive implementations. Note they take
43 * a variable, not an address.
44 */
45#define cpu_local_read(v) local_read(&__get_cpu_var(v))
46#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i))
47
48#define cpu_local_inc(v) local_inc(&__get_cpu_var(v))
49#define cpu_local_dec(v) local_dec(&__get_cpu_var(v))
50#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v))
51#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v))
52
53#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v))
54#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v))
55#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v))
56#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v))
57
58#endif /* _ASM_LOCAL_H */
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
index 4c1b73940351..33b80ced4bc1 100644
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -36,6 +36,11 @@ typedef struct
36 unsigned int unused : 16; 36 unsigned int unused : 16;
37} __attribute__ ((packed)) cpuid_t; 37} __attribute__ ((packed)) cpuid_t;
38 38
39static inline void get_cpu_id(cpuid_t *ptr)
40{
41 asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr));
42}
43
39struct cpuinfo_S390 44struct cpuinfo_S390
40{ 45{
41 cpuid_t cpu_id; 46 cpuid_t cpu_id;
diff --git a/include/asm-s390/sections.h b/include/asm-s390/sections.h
index 1c5a2c4ccdad..fbd9116eb17b 100644
--- a/include/asm-s390/sections.h
+++ b/include/asm-s390/sections.h
@@ -3,6 +3,6 @@
3 3
4#include <asm-generic/sections.h> 4#include <asm-generic/sections.h>
5 5
6extern char _eshared[]; 6extern char _eshared[], _ehead[];
7 7
8#endif 8#endif
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h
index 3388bb52597c..44c7aee2bd34 100644
--- a/include/asm-s390/setup.h
+++ b/include/asm-s390/setup.h
@@ -16,7 +16,6 @@
16 16
17#define PARMAREA 0x10400 17#define PARMAREA 0x10400
18#define MEMORY_CHUNKS 16 /* max 0x7fff */ 18#define MEMORY_CHUNKS 16 /* max 0x7fff */
19#define IPL_PARMBLOCK_ORIGIN 0x2000
20 19
21#ifndef __ASSEMBLY__ 20#ifndef __ASSEMBLY__
22 21
@@ -97,82 +96,9 @@ extern char vmpoff_cmd[];
97#define SET_CONSOLE_3215 do { console_mode = 2; } while (0) 96#define SET_CONSOLE_3215 do { console_mode = 2; } while (0)
98#define SET_CONSOLE_3270 do { console_mode = 3; } while (0) 97#define SET_CONSOLE_3270 do { console_mode = 3; } while (0)
99 98
100struct ipl_list_hdr {
101 u32 len;
102 u8 reserved1[3];
103 u8 version;
104 u32 blk0_len;
105 u8 pbt;
106 u8 flags;
107 u16 reserved2;
108} __attribute__((packed));
109
110struct ipl_block_fcp {
111 u8 reserved1[313-1];
112 u8 opt;
113 u8 reserved2[3];
114 u16 reserved3;
115 u16 devno;
116 u8 reserved4[4];
117 u64 wwpn;
118 u64 lun;
119 u32 bootprog;
120 u8 reserved5[12];
121 u64 br_lba;
122 u32 scp_data_len;
123 u8 reserved6[260];
124 u8 scp_data[];
125} __attribute__((packed));
126
127struct ipl_block_ccw {
128 u8 load_param[8];
129 u8 reserved1[84];
130 u8 reserved2[2];
131 u16 devno;
132 u8 vm_flags;
133 u8 reserved3[3];
134 u32 vm_parm_len;
135} __attribute__((packed));
136
137struct ipl_parameter_block {
138 struct ipl_list_hdr hdr;
139 union {
140 struct ipl_block_fcp fcp;
141 struct ipl_block_ccw ccw;
142 } ipl_info;
143} __attribute__((packed));
144
145#define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \
146 sizeof(struct ipl_block_fcp))
147
148#define IPL_PARM_BLK_CCW_LEN (sizeof(struct ipl_list_hdr) + \
149 sizeof(struct ipl_block_ccw))
150
151#define IPL_MAX_SUPPORTED_VERSION (0)
152
153/*
154 * IPL validity flags and parameters as detected in head.S
155 */
156extern u32 ipl_flags;
157extern u16 ipl_devno;
158
159extern void do_reipl(void);
160extern void ipl_save_parameters(void);
161
162enum {
163 IPL_DEVNO_VALID = 1,
164 IPL_PARMBLOCK_VALID = 2,
165 IPL_NSS_VALID = 4,
166};
167
168#define NSS_NAME_SIZE 8 99#define NSS_NAME_SIZE 8
169
170extern char kernel_nss_name[]; 100extern char kernel_nss_name[];
171 101
172#define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \
173 IPL_PARMBLOCK_ORIGIN)
174#define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.len)
175
176#else /* __ASSEMBLY__ */ 102#else /* __ASSEMBLY__ */
177 103
178#ifndef __s390x__ 104#ifndef __s390x__