2 * drivers/s390/char/sclp_cmd.c
4 * Copyright IBM Corp. 2007
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
6 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
9 #include <linux/completion.h>
10 #include <linux/init.h>
11 #include <linux/errno.h>
12 #include <linux/slab.h>
13 #include <linux/string.h>
14 #include <asm/chpid.h>
18 #define TAG "sclp_cmd: "
20 #define SCLP_CMDW_READ_SCP_INFO 0x00020001
21 #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
23 struct read_info_sccb
{
24 struct sccb_header header
; /* 0-7 */
27 u8 _reserved0
[24 - 11]; /* 11-15 */
28 u8 loadparm
[8]; /* 24-31 */
29 u8 _reserved1
[48 - 32]; /* 32-47 */
30 u64 facilities
; /* 48-55 */
31 u8 _reserved2
[84 - 56]; /* 56-83 */
33 u8 _reserved3
[91 - 85]; /* 85-90 */
35 u8 _reserved4
[100 - 92]; /* 92-99 */
36 u32 rnsize2
; /* 100-103 */
37 u64 rnmax2
; /* 104-111 */
38 u8 _reserved5
[4096 - 112]; /* 112-4095 */
39 } __attribute__((packed
, aligned(PAGE_SIZE
)));
41 static struct read_info_sccb __initdata early_read_info_sccb
;
42 static int __initdata early_read_info_sccb_valid
;
47 static int __init
sclp_cmd_sync_early(sclp_cmdw_t cmd
, void *sccb
)
52 rc
= sclp_service_call(cmd
, sccb
);
55 __load_psw_mask(PSW_BASE_BITS
| PSW_MASK_EXT
|
56 PSW_MASK_WAIT
| PSW_DEFAULT_KEY
);
59 /* Contents of the sccb might have changed. */
61 __ctl_clear_bit(0, 9);
65 void __init
sclp_read_info_early(void)
69 struct read_info_sccb
*sccb
;
70 sclp_cmdw_t commands
[] = {SCLP_CMDW_READ_SCP_INFO_FORCED
,
71 SCLP_CMDW_READ_SCP_INFO
};
73 sccb
= &early_read_info_sccb
;
74 for (i
= 0; i
< ARRAY_SIZE(commands
); i
++) {
76 memset(sccb
, 0, sizeof(*sccb
));
77 sccb
->header
.length
= sizeof(*sccb
);
78 sccb
->header
.control_mask
[2] = 0x80;
79 rc
= sclp_cmd_sync_early(commands
[i
], sccb
);
80 } while (rc
== -EBUSY
);
84 if (sccb
->header
.response_code
== 0x10) {
85 early_read_info_sccb_valid
= 1;
88 if (sccb
->header
.response_code
!= 0x1f0)
93 void __init
sclp_facilities_detect(void)
95 if (!early_read_info_sccb_valid
)
97 sclp_facilities
= early_read_info_sccb
.facilities
;
98 sclp_fac84
= early_read_info_sccb
.fac84
;
101 unsigned long long __init
sclp_memory_detect(void)
103 unsigned long long memsize
;
104 struct read_info_sccb
*sccb
;
106 if (!early_read_info_sccb_valid
)
108 sccb
= &early_read_info_sccb
;
110 memsize
= sccb
->rnsize
<< 20;
112 memsize
= sccb
->rnsize2
<< 20;
114 memsize
*= sccb
->rnmax
;
116 memsize
*= sccb
->rnmax2
;
121 * This function will be called after sclp_memory_detect(), which gets called
122 * early from early.c code. Therefore the sccb should have valid contents.
124 void __init
sclp_get_ipl_info(struct sclp_ipl_info
*info
)
126 struct read_info_sccb
*sccb
;
128 if (!early_read_info_sccb_valid
)
130 sccb
= &early_read_info_sccb
;
132 if (sccb
->flags
& 0x2)
134 memcpy(&info
->loadparm
, &sccb
->loadparm
, LOADPARM_LEN
);
137 static void sclp_sync_callback(struct sclp_req
*req
, void *data
)
139 struct completion
*completion
= data
;
141 complete(completion
);
144 static int do_sync_request(sclp_cmdw_t cmd
, void *sccb
)
146 struct completion completion
;
147 struct sclp_req
*request
;
150 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
153 request
->command
= cmd
;
154 request
->sccb
= sccb
;
155 request
->status
= SCLP_REQ_FILLED
;
156 request
->callback
= sclp_sync_callback
;
157 request
->callback_data
= &completion
;
158 init_completion(&completion
);
160 /* Perform sclp request. */
161 rc
= sclp_add_request(request
);
164 wait_for_completion(&completion
);
166 /* Check response. */
167 if (request
->status
!= SCLP_REQ_DONE
) {
168 printk(KERN_WARNING TAG
"sync request failed "
169 "(cmd=0x%08x, status=0x%02x)\n", cmd
, request
->status
);
178 * CPU configuration related functions.
181 #define SCLP_CMDW_READ_CPU_INFO 0x00010001
182 #define SCLP_CMDW_CONFIGURE_CPU 0x00110001
183 #define SCLP_CMDW_DECONFIGURE_CPU 0x00100001
185 struct read_cpu_info_sccb
{
186 struct sccb_header header
;
188 u16 offset_configured
;
191 u8 reserved
[4096 - 16];
192 } __attribute__((packed
, aligned(PAGE_SIZE
)));
194 static struct read_cpu_info_sccb __initdata early_read_cpu_info_sccb
;
195 static struct sclp_cpu_info __initdata sclp_cpu_info
;
197 static void sclp_fill_cpu_info(struct sclp_cpu_info
*info
,
198 struct read_cpu_info_sccb
*sccb
)
200 char *page
= (char *) sccb
;
202 memset(info
, 0, sizeof(*info
));
203 info
->configured
= sccb
->nr_configured
;
204 info
->standby
= sccb
->nr_standby
;
205 info
->combined
= sccb
->nr_configured
+ sccb
->nr_standby
;
206 info
->has_cpu_type
= sclp_fac84
& 0x1;
207 memcpy(&info
->cpu
, page
+ sccb
->offset_configured
,
208 info
->combined
* sizeof(struct sclp_cpu_entry
));
211 void __init
sclp_read_cpu_info_early(void)
214 struct read_cpu_info_sccb
*sccb
;
216 if (!SCLP_HAS_CPU_INFO
)
219 sccb
= &early_read_cpu_info_sccb
;
221 memset(sccb
, 0, sizeof(*sccb
));
222 sccb
->header
.length
= sizeof(*sccb
);
223 rc
= sclp_cmd_sync_early(SCLP_CMDW_READ_CPU_INFO
, sccb
);
224 } while (rc
== -EBUSY
);
228 if (sccb
->header
.response_code
!= 0x10)
230 sclp_fill_cpu_info(&sclp_cpu_info
, sccb
);
233 static int __init
sclp_get_cpu_info_early(struct sclp_cpu_info
*info
)
235 if (!SCLP_HAS_CPU_INFO
)
237 *info
= sclp_cpu_info
;
241 static int sclp_get_cpu_info_late(struct sclp_cpu_info
*info
)
244 struct read_cpu_info_sccb
*sccb
;
246 if (!SCLP_HAS_CPU_INFO
)
248 sccb
= (struct read_cpu_info_sccb
*) __get_free_page(GFP_KERNEL
252 memset(sccb
, 0, sizeof(*sccb
));
253 sccb
->header
.length
= sizeof(*sccb
);
254 rc
= do_sync_request(SCLP_CMDW_READ_CPU_INFO
, sccb
);
257 if (sccb
->header
.response_code
!= 0x0010) {
258 printk(KERN_WARNING TAG
"readcpuinfo failed "
259 "(response=0x%04x)\n", sccb
->header
.response_code
);
263 sclp_fill_cpu_info(info
, sccb
);
265 free_page((unsigned long) sccb
);
269 int __init_refok
sclp_get_cpu_info(struct sclp_cpu_info
*info
)
271 if (slab_is_available())
272 return sclp_get_cpu_info_late(info
);
273 return sclp_get_cpu_info_early(info
);
276 struct cpu_configure_sccb
{
277 struct sccb_header header
;
278 } __attribute__((packed
, aligned(8)));
280 static int do_cpu_configure(sclp_cmdw_t cmd
)
282 struct cpu_configure_sccb
*sccb
;
285 if (!SCLP_HAS_CPU_RECONFIG
)
288 * This is not going to cross a page boundary since we force
289 * kmalloc to have a minimum alignment of 8 bytes on s390.
291 sccb
= kzalloc(sizeof(*sccb
), GFP_KERNEL
| GFP_DMA
);
294 sccb
->header
.length
= sizeof(*sccb
);
295 rc
= do_sync_request(cmd
, sccb
);
298 switch (sccb
->header
.response_code
) {
303 printk(KERN_WARNING TAG
"configure cpu failed (cmd=0x%08x, "
304 "response=0x%04x)\n", cmd
, sccb
->header
.response_code
);
313 int sclp_cpu_configure(u8 cpu
)
315 return do_cpu_configure(SCLP_CMDW_CONFIGURE_CPU
| cpu
<< 8);
318 int sclp_cpu_deconfigure(u8 cpu
)
320 return do_cpu_configure(SCLP_CMDW_DECONFIGURE_CPU
| cpu
<< 8);
324 * Channel path configuration related functions.
327 #define SCLP_CMDW_CONFIGURE_CHPATH 0x000f0001
328 #define SCLP_CMDW_DECONFIGURE_CHPATH 0x000e0001
329 #define SCLP_CMDW_READ_CHPATH_INFORMATION 0x00030001
331 struct chp_cfg_sccb
{
332 struct sccb_header header
;
336 } __attribute__((packed
));
338 static int do_chp_configure(sclp_cmdw_t cmd
)
340 struct chp_cfg_sccb
*sccb
;
343 if (!SCLP_HAS_CHP_RECONFIG
)
346 sccb
= (struct chp_cfg_sccb
*) get_zeroed_page(GFP_KERNEL
| GFP_DMA
);
349 sccb
->header
.length
= sizeof(*sccb
);
350 rc
= do_sync_request(cmd
, sccb
);
353 switch (sccb
->header
.response_code
) {
360 printk(KERN_WARNING TAG
"configure channel-path failed "
361 "(cmd=0x%08x, response=0x%04x)\n", cmd
,
362 sccb
->header
.response_code
);
367 free_page((unsigned long) sccb
);
372 * sclp_chp_configure - perform configure channel-path sclp command
373 * @chpid: channel-path ID
375 * Perform configure channel-path command sclp command for specified chpid.
376 * Return 0 after command successfully finished, non-zero otherwise.
378 int sclp_chp_configure(struct chp_id chpid
)
380 return do_chp_configure(SCLP_CMDW_CONFIGURE_CHPATH
| chpid
.id
<< 8);
384 * sclp_chp_deconfigure - perform deconfigure channel-path sclp command
385 * @chpid: channel-path ID
387 * Perform deconfigure channel-path command sclp command for specified chpid
388 * and wait for completion. On success return 0. Return non-zero otherwise.
390 int sclp_chp_deconfigure(struct chp_id chpid
)
392 return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH
| chpid
.id
<< 8);
395 struct chp_info_sccb
{
396 struct sccb_header header
;
397 u8 recognized
[SCLP_CHP_INFO_MASK_SIZE
];
398 u8 standby
[SCLP_CHP_INFO_MASK_SIZE
];
399 u8 configured
[SCLP_CHP_INFO_MASK_SIZE
];
403 } __attribute__((packed
));
406 * sclp_chp_read_info - perform read channel-path information sclp command
407 * @info: resulting channel-path information data
409 * Perform read channel-path information sclp command and wait for completion.
410 * On success, store channel-path information in @info and return 0. Return
411 * non-zero otherwise.
413 int sclp_chp_read_info(struct sclp_chp_info
*info
)
415 struct chp_info_sccb
*sccb
;
418 if (!SCLP_HAS_CHP_INFO
)
421 sccb
= (struct chp_info_sccb
*) get_zeroed_page(GFP_KERNEL
| GFP_DMA
);
424 sccb
->header
.length
= sizeof(*sccb
);
425 rc
= do_sync_request(SCLP_CMDW_READ_CHPATH_INFORMATION
, sccb
);
428 if (sccb
->header
.response_code
!= 0x0010) {
429 printk(KERN_WARNING TAG
"read channel-path info failed "
430 "(response=0x%04x)\n", sccb
->header
.response_code
);
434 memcpy(info
->recognized
, sccb
->recognized
, SCLP_CHP_INFO_MASK_SIZE
);
435 memcpy(info
->standby
, sccb
->standby
, SCLP_CHP_INFO_MASK_SIZE
);
436 memcpy(info
->configured
, sccb
->configured
, SCLP_CHP_INFO_MASK_SIZE
);
438 free_page((unsigned long) sccb
);