2 * drivers/s390/char/sclp_cmd.c
4 * Copyright IBM Corp. 2007
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
8 #include <linux/completion.h>
9 #include <linux/init.h>
10 #include <linux/errno.h>
11 #include <linux/slab.h>
12 #include <linux/string.h>
16 #define TAG "sclp_cmd: "
18 #define SCLP_CMDW_READ_SCP_INFO 0x00020001
19 #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
21 struct read_info_sccb
{
22 struct sccb_header header
; /* 0-7 */
25 u8 _reserved0
[24 - 11]; /* 11-15 */
26 u8 loadparm
[8]; /* 24-31 */
27 u8 _reserved1
[48 - 32]; /* 32-47 */
28 u64 facilities
; /* 48-55 */
29 u8 _reserved2
[84 - 56]; /* 56-83 */
31 u8 _reserved3
[91 - 85]; /* 85-90 */
33 u8 _reserved4
[100 - 92]; /* 92-99 */
34 u32 rnsize2
; /* 100-103 */
35 u64 rnmax2
; /* 104-111 */
36 u8 _reserved5
[4096 - 112]; /* 112-4095 */
37 } __attribute__((packed
, aligned(PAGE_SIZE
)));
39 static struct read_info_sccb __initdata early_read_info_sccb
;
40 static int __initdata early_read_info_sccb_valid
;
45 static int __init
sclp_cmd_sync_early(sclp_cmdw_t cmd
, void *sccb
)
50 rc
= sclp_service_call(cmd
, sccb
);
53 __load_psw_mask(PSW_BASE_BITS
| PSW_MASK_EXT
|
54 PSW_MASK_WAIT
| PSW_DEFAULT_KEY
);
57 /* Contents of the sccb might have changed. */
59 __ctl_clear_bit(0, 9);
63 void __init
sclp_read_info_early(void)
67 struct read_info_sccb
*sccb
;
68 sclp_cmdw_t commands
[] = {SCLP_CMDW_READ_SCP_INFO_FORCED
,
69 SCLP_CMDW_READ_SCP_INFO
};
71 sccb
= &early_read_info_sccb
;
72 for (i
= 0; i
< ARRAY_SIZE(commands
); i
++) {
74 memset(sccb
, 0, sizeof(*sccb
));
75 sccb
->header
.length
= sizeof(*sccb
);
76 sccb
->header
.control_mask
[2] = 0x80;
77 rc
= sclp_cmd_sync_early(commands
[i
], sccb
);
78 } while (rc
== -EBUSY
);
82 if (sccb
->header
.response_code
== 0x10) {
83 early_read_info_sccb_valid
= 1;
86 if (sccb
->header
.response_code
!= 0x1f0)
91 void __init
sclp_facilities_detect(void)
93 if (!early_read_info_sccb_valid
)
95 sclp_facilities
= early_read_info_sccb
.facilities
;
96 sclp_fac84
= early_read_info_sccb
.fac84
;
99 unsigned long long __init
sclp_memory_detect(void)
101 unsigned long long memsize
;
102 struct read_info_sccb
*sccb
;
104 if (!early_read_info_sccb_valid
)
106 sccb
= &early_read_info_sccb
;
108 memsize
= sccb
->rnsize
<< 20;
110 memsize
= sccb
->rnsize2
<< 20;
112 memsize
*= sccb
->rnmax
;
114 memsize
*= sccb
->rnmax2
;
119 * This function will be called after sclp_memory_detect(), which gets called
120 * early from early.c code. Therefore the sccb should have valid contents.
122 void __init
sclp_get_ipl_info(struct sclp_ipl_info
*info
)
124 struct read_info_sccb
*sccb
;
126 if (!early_read_info_sccb_valid
)
128 sccb
= &early_read_info_sccb
;
130 if (sccb
->flags
& 0x2)
132 memcpy(&info
->loadparm
, &sccb
->loadparm
, LOADPARM_LEN
);
135 static void sclp_sync_callback(struct sclp_req
*req
, void *data
)
137 struct completion
*completion
= data
;
139 complete(completion
);
142 static int do_sync_request(sclp_cmdw_t cmd
, void *sccb
)
144 struct completion completion
;
145 struct sclp_req
*request
;
148 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
151 request
->command
= cmd
;
152 request
->sccb
= sccb
;
153 request
->status
= SCLP_REQ_FILLED
;
154 request
->callback
= sclp_sync_callback
;
155 request
->callback_data
= &completion
;
156 init_completion(&completion
);
158 /* Perform sclp request. */
159 rc
= sclp_add_request(request
);
162 wait_for_completion(&completion
);
164 /* Check response. */
165 if (request
->status
!= SCLP_REQ_DONE
) {
166 printk(KERN_WARNING TAG
"sync request failed "
167 "(cmd=0x%08x, status=0x%02x)\n", cmd
, request
->status
);
176 * CPU configuration related functions.
179 #define SCLP_CMDW_READ_CPU_INFO 0x00010001
180 #define SCLP_CMDW_CONFIGURE_CPU 0x00110001
181 #define SCLP_CMDW_DECONFIGURE_CPU 0x00100001
183 struct read_cpu_info_sccb
{
184 struct sccb_header header
;
186 u16 offset_configured
;
189 u8 reserved
[4096 - 16];
190 } __attribute__((packed
, aligned(PAGE_SIZE
)));
192 static struct read_cpu_info_sccb __initdata early_read_cpu_info_sccb
;
193 static struct sclp_cpu_info __initdata sclp_cpu_info
;
195 static void sclp_fill_cpu_info(struct sclp_cpu_info
*info
,
196 struct read_cpu_info_sccb
*sccb
)
198 char *page
= (char *) sccb
;
200 memset(info
, 0, sizeof(*info
));
201 info
->configured
= sccb
->nr_configured
;
202 info
->standby
= sccb
->nr_standby
;
203 info
->combined
= sccb
->nr_configured
+ sccb
->nr_standby
;
204 info
->has_cpu_type
= sclp_fac84
& 0x1;
205 memcpy(&info
->cpu
, page
+ sccb
->offset_configured
,
206 info
->combined
* sizeof(struct sclp_cpu_entry
));
209 void __init
sclp_read_cpu_info_early(void)
212 struct read_cpu_info_sccb
*sccb
;
214 if (!SCLP_HAS_CPU_INFO
)
217 sccb
= &early_read_cpu_info_sccb
;
219 memset(sccb
, 0, sizeof(*sccb
));
220 sccb
->header
.length
= sizeof(*sccb
);
221 rc
= sclp_cmd_sync_early(SCLP_CMDW_READ_CPU_INFO
, sccb
);
222 } while (rc
== -EBUSY
);
226 if (sccb
->header
.response_code
!= 0x10)
228 sclp_fill_cpu_info(&sclp_cpu_info
, sccb
);
231 static int __init
sclp_get_cpu_info_early(struct sclp_cpu_info
*info
)
233 if (!SCLP_HAS_CPU_INFO
)
235 *info
= sclp_cpu_info
;
239 static int sclp_get_cpu_info_late(struct sclp_cpu_info
*info
)
242 struct read_cpu_info_sccb
*sccb
;
244 if (!SCLP_HAS_CPU_INFO
)
246 sccb
= (struct read_cpu_info_sccb
*) __get_free_page(GFP_KERNEL
250 memset(sccb
, 0, sizeof(*sccb
));
251 sccb
->header
.length
= sizeof(*sccb
);
252 rc
= do_sync_request(SCLP_CMDW_READ_CPU_INFO
, sccb
);
255 if (sccb
->header
.response_code
!= 0x0010) {
256 printk(KERN_WARNING TAG
"readcpuinfo failed "
257 "(response=0x%04x)\n", sccb
->header
.response_code
);
261 sclp_fill_cpu_info(info
, sccb
);
263 free_page((unsigned long) sccb
);
267 int __init_refok
sclp_get_cpu_info(struct sclp_cpu_info
*info
)
269 if (slab_is_available())
270 return sclp_get_cpu_info_late(info
);
271 return sclp_get_cpu_info_early(info
);
274 struct cpu_configure_sccb
{
275 struct sccb_header header
;
276 } __attribute__((packed
, aligned(8)));
278 static int do_cpu_configure(sclp_cmdw_t cmd
)
280 struct cpu_configure_sccb
*sccb
;
283 if (!SCLP_HAS_CPU_RECONFIG
)
286 * This is not going to cross a page boundary since we force
287 * kmalloc to have a minimum alignment of 8 bytes on s390.
289 sccb
= kzalloc(sizeof(*sccb
), GFP_KERNEL
| GFP_DMA
);
292 sccb
->header
.length
= sizeof(*sccb
);
293 rc
= do_sync_request(cmd
, sccb
);
296 switch (sccb
->header
.response_code
) {
301 printk(KERN_WARNING TAG
"configure cpu failed (cmd=0x%08x, "
302 "response=0x%04x)\n", cmd
, sccb
->header
.response_code
);
311 int sclp_cpu_configure(u8 cpu
)
313 return do_cpu_configure(SCLP_CMDW_CONFIGURE_CPU
| cpu
<< 8);
316 int sclp_cpu_deconfigure(u8 cpu
)
318 return do_cpu_configure(SCLP_CMDW_DECONFIGURE_CPU
| cpu
<< 8);