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 void sclp_fill_cpu_info(struct sclp_cpu_info
*info
,
195 struct read_cpu_info_sccb
*sccb
)
197 char *page
= (char *) sccb
;
199 memset(info
, 0, sizeof(*info
));
200 info
->configured
= sccb
->nr_configured
;
201 info
->standby
= sccb
->nr_standby
;
202 info
->combined
= sccb
->nr_configured
+ sccb
->nr_standby
;
203 info
->has_cpu_type
= sclp_fac84
& 0x1;
204 memcpy(&info
->cpu
, page
+ sccb
->offset_configured
,
205 info
->combined
* sizeof(struct sclp_cpu_entry
));
208 int sclp_get_cpu_info(struct sclp_cpu_info
*info
)
211 struct read_cpu_info_sccb
*sccb
;
213 if (!SCLP_HAS_CPU_INFO
)
215 sccb
= (void *) get_zeroed_page(GFP_KERNEL
| GFP_DMA
);
218 sccb
->header
.length
= sizeof(*sccb
);
219 rc
= do_sync_request(SCLP_CMDW_READ_CPU_INFO
, sccb
);
222 if (sccb
->header
.response_code
!= 0x0010) {
223 printk(KERN_WARNING TAG
"readcpuinfo failed "
224 "(response=0x%04x)\n", sccb
->header
.response_code
);
228 sclp_fill_cpu_info(info
, sccb
);
230 free_page((unsigned long) sccb
);
234 struct cpu_configure_sccb
{
235 struct sccb_header header
;
236 } __attribute__((packed
, aligned(8)));
238 static int do_cpu_configure(sclp_cmdw_t cmd
)
240 struct cpu_configure_sccb
*sccb
;
243 if (!SCLP_HAS_CPU_RECONFIG
)
246 * This is not going to cross a page boundary since we force
247 * kmalloc to have a minimum alignment of 8 bytes on s390.
249 sccb
= kzalloc(sizeof(*sccb
), GFP_KERNEL
| GFP_DMA
);
252 sccb
->header
.length
= sizeof(*sccb
);
253 rc
= do_sync_request(cmd
, sccb
);
256 switch (sccb
->header
.response_code
) {
261 printk(KERN_WARNING TAG
"configure cpu failed (cmd=0x%08x, "
262 "response=0x%04x)\n", cmd
, sccb
->header
.response_code
);
271 int sclp_cpu_configure(u8 cpu
)
273 return do_cpu_configure(SCLP_CMDW_CONFIGURE_CPU
| cpu
<< 8);
276 int sclp_cpu_deconfigure(u8 cpu
)
278 return do_cpu_configure(SCLP_CMDW_DECONFIGURE_CPU
| cpu
<< 8);
282 * Channel path configuration related functions.
285 #define SCLP_CMDW_CONFIGURE_CHPATH 0x000f0001
286 #define SCLP_CMDW_DECONFIGURE_CHPATH 0x000e0001
287 #define SCLP_CMDW_READ_CHPATH_INFORMATION 0x00030001
289 struct chp_cfg_sccb
{
290 struct sccb_header header
;
294 } __attribute__((packed
));
296 static int do_chp_configure(sclp_cmdw_t cmd
)
298 struct chp_cfg_sccb
*sccb
;
301 if (!SCLP_HAS_CHP_RECONFIG
)
304 sccb
= (struct chp_cfg_sccb
*) get_zeroed_page(GFP_KERNEL
| GFP_DMA
);
307 sccb
->header
.length
= sizeof(*sccb
);
308 rc
= do_sync_request(cmd
, sccb
);
311 switch (sccb
->header
.response_code
) {
318 printk(KERN_WARNING TAG
"configure channel-path failed "
319 "(cmd=0x%08x, response=0x%04x)\n", cmd
,
320 sccb
->header
.response_code
);
325 free_page((unsigned long) sccb
);
330 * sclp_chp_configure - perform configure channel-path sclp command
331 * @chpid: channel-path ID
333 * Perform configure channel-path command sclp command for specified chpid.
334 * Return 0 after command successfully finished, non-zero otherwise.
336 int sclp_chp_configure(struct chp_id chpid
)
338 return do_chp_configure(SCLP_CMDW_CONFIGURE_CHPATH
| chpid
.id
<< 8);
342 * sclp_chp_deconfigure - perform deconfigure channel-path sclp command
343 * @chpid: channel-path ID
345 * Perform deconfigure channel-path command sclp command for specified chpid
346 * and wait for completion. On success return 0. Return non-zero otherwise.
348 int sclp_chp_deconfigure(struct chp_id chpid
)
350 return do_chp_configure(SCLP_CMDW_DECONFIGURE_CHPATH
| chpid
.id
<< 8);
353 struct chp_info_sccb
{
354 struct sccb_header header
;
355 u8 recognized
[SCLP_CHP_INFO_MASK_SIZE
];
356 u8 standby
[SCLP_CHP_INFO_MASK_SIZE
];
357 u8 configured
[SCLP_CHP_INFO_MASK_SIZE
];
361 } __attribute__((packed
));
364 * sclp_chp_read_info - perform read channel-path information sclp command
365 * @info: resulting channel-path information data
367 * Perform read channel-path information sclp command and wait for completion.
368 * On success, store channel-path information in @info and return 0. Return
369 * non-zero otherwise.
371 int sclp_chp_read_info(struct sclp_chp_info
*info
)
373 struct chp_info_sccb
*sccb
;
376 if (!SCLP_HAS_CHP_INFO
)
379 sccb
= (struct chp_info_sccb
*) get_zeroed_page(GFP_KERNEL
| GFP_DMA
);
382 sccb
->header
.length
= sizeof(*sccb
);
383 rc
= do_sync_request(SCLP_CMDW_READ_CHPATH_INFORMATION
, sccb
);
386 if (sccb
->header
.response_code
!= 0x0010) {
387 printk(KERN_WARNING TAG
"read channel-path info failed "
388 "(response=0x%04x)\n", sccb
->header
.response_code
);
392 memcpy(info
->recognized
, sccb
->recognized
, SCLP_CHP_INFO_MASK_SIZE
);
393 memcpy(info
->standby
, sccb
->standby
, SCLP_CHP_INFO_MASK_SIZE
);
394 memcpy(info
->configured
, sccb
->configured
, SCLP_CHP_INFO_MASK_SIZE
);
396 free_page((unsigned long) sccb
);