diff options
author | Michael Holzheu <holzheu@linux.vnet.ibm.com> | 2013-11-13 04:38:27 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-11-15 08:08:41 -0500 |
commit | acf6a004e6a35dad17032e3b7c5a046c29957e65 (patch) | |
tree | 377fb42d62773abbb2bbddecdfff8b8e3eb8f3f8 | |
parent | e657d8fe2faf49ed5d35e2325bd0f1712b8058cd (diff) |
s390/sclp: Move early code from sclp_cmd.c to sclp_early.c
The early SCLP driver code in sclp_cmd.c belongs to sclp_early.c
because it is independent from the 'normal' SCLP driver. So move
it to sclp_early.c
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r-- | arch/s390/include/asm/ctl_reg.h | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp.h | 6 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cmd.c | 180 | ||||
-rw-r--r-- | drivers/s390/char/sclp_early.c | 162 |
4 files changed, 178 insertions, 172 deletions
diff --git a/arch/s390/include/asm/ctl_reg.h b/arch/s390/include/asm/ctl_reg.h index 9b69c0befdca..4e63f1a13600 100644 --- a/arch/s390/include/asm/ctl_reg.h +++ b/arch/s390/include/asm/ctl_reg.h | |||
@@ -7,6 +7,8 @@ | |||
7 | #ifndef __ASM_CTL_REG_H | 7 | #ifndef __ASM_CTL_REG_H |
8 | #define __ASM_CTL_REG_H | 8 | #define __ASM_CTL_REG_H |
9 | 9 | ||
10 | #include <linux/bug.h> | ||
11 | |||
10 | #ifdef CONFIG_64BIT | 12 | #ifdef CONFIG_64BIT |
11 | # define __CTL_LOAD "lctlg" | 13 | # define __CTL_LOAD "lctlg" |
12 | # define __CTL_STORE "stctg" | 14 | # define __CTL_STORE "stctg" |
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index 9cb8076f66c4..6fbe09686d18 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h | |||
@@ -99,6 +99,7 @@ struct init_sccb { | |||
99 | } __attribute__((packed)); | 99 | } __attribute__((packed)); |
100 | 100 | ||
101 | extern u64 sclp_facilities; | 101 | extern u64 sclp_facilities; |
102 | |||
102 | #define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) | 103 | #define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL) |
103 | #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) | 104 | #define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) |
104 | #define SCLP_HAS_CPU_INFO (sclp_facilities & 0x0800000000000000ULL) | 105 | #define SCLP_HAS_CPU_INFO (sclp_facilities & 0x0800000000000000ULL) |
@@ -172,7 +173,6 @@ int sclp_deactivate(void); | |||
172 | int sclp_reactivate(void); | 173 | int sclp_reactivate(void); |
173 | int sclp_service_call(sclp_cmdw_t command, void *sccb); | 174 | int sclp_service_call(sclp_cmdw_t command, void *sccb); |
174 | int sclp_sync_request(sclp_cmdw_t command, void *sccb); | 175 | int sclp_sync_request(sclp_cmdw_t command, void *sccb); |
175 | int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb); | ||
176 | 176 | ||
177 | int sclp_sdias_init(void); | 177 | int sclp_sdias_init(void); |
178 | void sclp_sdias_exit(void); | 178 | void sclp_sdias_exit(void); |
@@ -180,6 +180,10 @@ void sclp_sdias_exit(void); | |||
180 | extern int sclp_console_pages; | 180 | extern int sclp_console_pages; |
181 | extern int sclp_console_drop; | 181 | extern int sclp_console_drop; |
182 | extern unsigned long sclp_console_full; | 182 | extern unsigned long sclp_console_full; |
183 | extern u8 sclp_fac84; | ||
184 | extern unsigned long long sclp_rzm; | ||
185 | extern unsigned long long sclp_rnmax; | ||
186 | extern __initdata int sclp_early_read_info_sccb_valid; | ||
183 | 187 | ||
184 | /* useful inlines */ | 188 | /* useful inlines */ |
185 | 189 | ||
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 5bbe6db988b9..eaa21d542c5c 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c | |||
@@ -28,168 +28,6 @@ | |||
28 | 28 | ||
29 | #include "sclp.h" | 29 | #include "sclp.h" |
30 | 30 | ||
31 | #define SCLP_CMDW_READ_SCP_INFO 0x00020001 | ||
32 | #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 | ||
33 | |||
34 | struct read_info_sccb { | ||
35 | struct sccb_header header; /* 0-7 */ | ||
36 | u16 rnmax; /* 8-9 */ | ||
37 | u8 rnsize; /* 10 */ | ||
38 | u8 _reserved0[24 - 11]; /* 11-15 */ | ||
39 | u8 loadparm[8]; /* 24-31 */ | ||
40 | u8 _reserved1[48 - 32]; /* 32-47 */ | ||
41 | u64 facilities; /* 48-55 */ | ||
42 | u8 _reserved2[84 - 56]; /* 56-83 */ | ||
43 | u8 fac84; /* 84 */ | ||
44 | u8 fac85; /* 85 */ | ||
45 | u8 _reserved3[91 - 86]; /* 86-90 */ | ||
46 | u8 flags; /* 91 */ | ||
47 | u8 _reserved4[100 - 92]; /* 92-99 */ | ||
48 | u32 rnsize2; /* 100-103 */ | ||
49 | u64 rnmax2; /* 104-111 */ | ||
50 | u8 _reserved5[4096 - 112]; /* 112-4095 */ | ||
51 | } __attribute__((packed, aligned(PAGE_SIZE))); | ||
52 | |||
53 | static struct init_sccb __initdata early_event_mask_sccb __aligned(PAGE_SIZE); | ||
54 | static struct read_info_sccb __initdata early_read_info_sccb; | ||
55 | static int __initdata early_read_info_sccb_valid; | ||
56 | |||
57 | u64 sclp_facilities; | ||
58 | static u8 sclp_fac84; | ||
59 | static unsigned long long rzm; | ||
60 | static unsigned long long rnmax; | ||
61 | |||
62 | int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb) | ||
63 | { | ||
64 | int rc; | ||
65 | |||
66 | __ctl_set_bit(0, 9); | ||
67 | rc = sclp_service_call(cmd, sccb); | ||
68 | if (rc) | ||
69 | goto out; | ||
70 | __load_psw_mask(PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | | ||
71 | PSW_MASK_BA | PSW_MASK_EXT | PSW_MASK_WAIT); | ||
72 | local_irq_disable(); | ||
73 | out: | ||
74 | /* Contents of the sccb might have changed. */ | ||
75 | barrier(); | ||
76 | __ctl_clear_bit(0, 9); | ||
77 | return rc; | ||
78 | } | ||
79 | |||
80 | static void __init sclp_read_info_early(void) | ||
81 | { | ||
82 | int rc; | ||
83 | int i; | ||
84 | struct read_info_sccb *sccb; | ||
85 | sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, | ||
86 | SCLP_CMDW_READ_SCP_INFO}; | ||
87 | |||
88 | sccb = &early_read_info_sccb; | ||
89 | for (i = 0; i < ARRAY_SIZE(commands); i++) { | ||
90 | do { | ||
91 | memset(sccb, 0, sizeof(*sccb)); | ||
92 | sccb->header.length = sizeof(*sccb); | ||
93 | sccb->header.function_code = 0x80; | ||
94 | sccb->header.control_mask[2] = 0x80; | ||
95 | rc = sclp_cmd_sync_early(commands[i], sccb); | ||
96 | } while (rc == -EBUSY); | ||
97 | |||
98 | if (rc) | ||
99 | break; | ||
100 | if (sccb->header.response_code == 0x10) { | ||
101 | early_read_info_sccb_valid = 1; | ||
102 | break; | ||
103 | } | ||
104 | if (sccb->header.response_code != 0x1f0) | ||
105 | break; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | static void __init sclp_event_mask_early(void) | ||
110 | { | ||
111 | struct init_sccb *sccb = &early_event_mask_sccb; | ||
112 | int rc; | ||
113 | |||
114 | do { | ||
115 | memset(sccb, 0, sizeof(*sccb)); | ||
116 | sccb->header.length = sizeof(*sccb); | ||
117 | sccb->mask_length = sizeof(sccb_mask_t); | ||
118 | rc = sclp_cmd_sync_early(SCLP_CMDW_WRITE_EVENT_MASK, sccb); | ||
119 | } while (rc == -EBUSY); | ||
120 | } | ||
121 | |||
122 | void __init sclp_facilities_detect(void) | ||
123 | { | ||
124 | struct read_info_sccb *sccb; | ||
125 | |||
126 | sclp_read_info_early(); | ||
127 | if (!early_read_info_sccb_valid) | ||
128 | return; | ||
129 | |||
130 | sccb = &early_read_info_sccb; | ||
131 | sclp_facilities = sccb->facilities; | ||
132 | sclp_fac84 = sccb->fac84; | ||
133 | if (sccb->fac85 & 0x02) | ||
134 | S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; | ||
135 | rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; | ||
136 | rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; | ||
137 | rzm <<= 20; | ||
138 | |||
139 | sclp_event_mask_early(); | ||
140 | } | ||
141 | |||
142 | bool __init sclp_has_linemode(void) | ||
143 | { | ||
144 | struct init_sccb *sccb = &early_event_mask_sccb; | ||
145 | |||
146 | if (sccb->header.response_code != 0x20) | ||
147 | return 0; | ||
148 | if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK))) | ||
149 | return 0; | ||
150 | if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK))) | ||
151 | return 0; | ||
152 | return 1; | ||
153 | } | ||
154 | |||
155 | bool __init sclp_has_vt220(void) | ||
156 | { | ||
157 | struct init_sccb *sccb = &early_event_mask_sccb; | ||
158 | |||
159 | if (sccb->header.response_code != 0x20) | ||
160 | return 0; | ||
161 | if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK) | ||
162 | return 1; | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | unsigned long long sclp_get_rnmax(void) | ||
167 | { | ||
168 | return rnmax; | ||
169 | } | ||
170 | |||
171 | unsigned long long sclp_get_rzm(void) | ||
172 | { | ||
173 | return rzm; | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * This function will be called after sclp_facilities_detect(), which gets | ||
178 | * called from early.c code. Therefore the sccb should have valid contents. | ||
179 | */ | ||
180 | void __init sclp_get_ipl_info(struct sclp_ipl_info *info) | ||
181 | { | ||
182 | struct read_info_sccb *sccb; | ||
183 | |||
184 | if (!early_read_info_sccb_valid) | ||
185 | return; | ||
186 | sccb = &early_read_info_sccb; | ||
187 | info->is_valid = 1; | ||
188 | if (sccb->flags & 0x2) | ||
189 | info->has_dump = 1; | ||
190 | memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN); | ||
191 | } | ||
192 | |||
193 | static void sclp_sync_callback(struct sclp_req *req, void *data) | 31 | static void sclp_sync_callback(struct sclp_req *req, void *data) |
194 | { | 32 | { |
195 | struct completion *completion = data; | 33 | struct completion *completion = data; |
@@ -356,14 +194,14 @@ struct assign_storage_sccb { | |||
356 | 194 | ||
357 | int arch_get_memory_phys_device(unsigned long start_pfn) | 195 | int arch_get_memory_phys_device(unsigned long start_pfn) |
358 | { | 196 | { |
359 | if (!rzm) | 197 | if (!sclp_rzm) |
360 | return 0; | 198 | return 0; |
361 | return PFN_PHYS(start_pfn) >> ilog2(rzm); | 199 | return PFN_PHYS(start_pfn) >> ilog2(sclp_rzm); |
362 | } | 200 | } |
363 | 201 | ||
364 | static unsigned long long rn2addr(u16 rn) | 202 | static unsigned long long rn2addr(u16 rn) |
365 | { | 203 | { |
366 | return (unsigned long long) (rn - 1) * rzm; | 204 | return (unsigned long long) (rn - 1) * sclp_rzm; |
367 | } | 205 | } |
368 | 206 | ||
369 | static int do_assign_storage(sclp_cmdw_t cmd, u16 rn) | 207 | static int do_assign_storage(sclp_cmdw_t cmd, u16 rn) |
@@ -404,7 +242,7 @@ static int sclp_assign_storage(u16 rn) | |||
404 | if (rc) | 242 | if (rc) |
405 | return rc; | 243 | return rc; |
406 | start = rn2addr(rn); | 244 | start = rn2addr(rn); |
407 | storage_key_init_range(start, start + rzm); | 245 | storage_key_init_range(start, start + sclp_rzm); |
408 | return 0; | 246 | return 0; |
409 | } | 247 | } |
410 | 248 | ||
@@ -462,7 +300,7 @@ static int sclp_mem_change_state(unsigned long start, unsigned long size, | |||
462 | istart = rn2addr(incr->rn); | 300 | istart = rn2addr(incr->rn); |
463 | if (start + size - 1 < istart) | 301 | if (start + size - 1 < istart) |
464 | break; | 302 | break; |
465 | if (start > istart + rzm - 1) | 303 | if (start > istart + sclp_rzm - 1) |
466 | continue; | 304 | continue; |
467 | if (online) | 305 | if (online) |
468 | rc |= sclp_assign_storage(incr->rn); | 306 | rc |= sclp_assign_storage(incr->rn); |
@@ -526,7 +364,7 @@ static void __init add_memory_merged(u16 rn) | |||
526 | if (!first_rn) | 364 | if (!first_rn) |
527 | goto skip_add; | 365 | goto skip_add; |
528 | start = rn2addr(first_rn); | 366 | start = rn2addr(first_rn); |
529 | size = (unsigned long long ) num * rzm; | 367 | size = (unsigned long long) num * sclp_rzm; |
530 | if (start >= VMEM_MAX_PHYS) | 368 | if (start >= VMEM_MAX_PHYS) |
531 | goto skip_add; | 369 | goto skip_add; |
532 | if (start + size > VMEM_MAX_PHYS) | 370 | if (start + size > VMEM_MAX_PHYS) |
@@ -574,7 +412,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned) | |||
574 | } | 412 | } |
575 | if (!assigned) | 413 | if (!assigned) |
576 | new_incr->rn = last_rn + 1; | 414 | new_incr->rn = last_rn + 1; |
577 | if (new_incr->rn > rnmax) { | 415 | if (new_incr->rn > sclp_rnmax) { |
578 | kfree(new_incr); | 416 | kfree(new_incr); |
579 | return; | 417 | return; |
580 | } | 418 | } |
@@ -617,7 +455,7 @@ static int __init sclp_detect_standby_memory(void) | |||
617 | 455 | ||
618 | if (OLDMEM_BASE) /* No standby memory in kdump mode */ | 456 | if (OLDMEM_BASE) /* No standby memory in kdump mode */ |
619 | return 0; | 457 | return 0; |
620 | if (!early_read_info_sccb_valid) | 458 | if (!sclp_early_read_info_sccb_valid) |
621 | return 0; | 459 | return 0; |
622 | if ((sclp_facilities & 0xe00000000000ULL) != 0xe00000000000ULL) | 460 | if ((sclp_facilities & 0xe00000000000ULL) != 0xe00000000000ULL) |
623 | return 0; | 461 | return 0; |
@@ -661,7 +499,7 @@ static int __init sclp_detect_standby_memory(void) | |||
661 | } | 499 | } |
662 | if (rc || list_empty(&sclp_mem_list)) | 500 | if (rc || list_empty(&sclp_mem_list)) |
663 | goto out; | 501 | goto out; |
664 | for (i = 1; i <= rnmax - assigned; i++) | 502 | for (i = 1; i <= sclp_rnmax - assigned; i++) |
665 | insert_increment(0, 1, 0); | 503 | insert_increment(0, 1, 0); |
666 | rc = register_memory_notifier(&sclp_mem_nb); | 504 | rc = register_memory_notifier(&sclp_mem_nb); |
667 | if (rc) | 505 | if (rc) |
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index 775112964eef..cbec45fdcc59 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c | |||
@@ -7,14 +7,176 @@ | |||
7 | #define KMSG_COMPONENT "sclp_early" | 7 | #define KMSG_COMPONENT "sclp_early" |
8 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | 8 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt |
9 | 9 | ||
10 | #include <asm/ctl_reg.h> | ||
10 | #include <asm/sclp.h> | 11 | #include <asm/sclp.h> |
11 | #include <asm/ipl.h> | 12 | #include <asm/ipl.h> |
12 | #include "sclp_sdias.h" | 13 | #include "sclp_sdias.h" |
13 | #include "sclp.h" | 14 | #include "sclp.h" |
14 | 15 | ||
16 | #define SCLP_CMDW_READ_SCP_INFO 0x00020001 | ||
17 | #define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001 | ||
18 | |||
19 | struct read_info_sccb { | ||
20 | struct sccb_header header; /* 0-7 */ | ||
21 | u16 rnmax; /* 8-9 */ | ||
22 | u8 rnsize; /* 10 */ | ||
23 | u8 _reserved0[24 - 11]; /* 11-15 */ | ||
24 | u8 loadparm[8]; /* 24-31 */ | ||
25 | u8 _reserved1[48 - 32]; /* 32-47 */ | ||
26 | u64 facilities; /* 48-55 */ | ||
27 | u8 _reserved2[84 - 56]; /* 56-83 */ | ||
28 | u8 fac84; /* 84 */ | ||
29 | u8 fac85; /* 85 */ | ||
30 | u8 _reserved3[91 - 86]; /* 86-90 */ | ||
31 | u8 flags; /* 91 */ | ||
32 | u8 _reserved4[100 - 92]; /* 92-99 */ | ||
33 | u32 rnsize2; /* 100-103 */ | ||
34 | u64 rnmax2; /* 104-111 */ | ||
35 | u8 _reserved5[4096 - 112]; /* 112-4095 */ | ||
36 | } __packed __aligned(PAGE_SIZE); | ||
37 | |||
38 | static __initdata struct init_sccb early_event_mask_sccb __aligned(PAGE_SIZE); | ||
39 | static __initdata struct read_info_sccb early_read_info_sccb; | ||
15 | static __initdata char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE); | 40 | static __initdata char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE); |
16 | static unsigned long sclp_hsa_size; | 41 | static unsigned long sclp_hsa_size; |
17 | 42 | ||
43 | __initdata int sclp_early_read_info_sccb_valid; | ||
44 | u64 sclp_facilities; | ||
45 | u8 sclp_fac84; | ||
46 | unsigned long long sclp_rzm; | ||
47 | unsigned long long sclp_rnmax; | ||
48 | |||
49 | static int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb) | ||
50 | { | ||
51 | int rc; | ||
52 | |||
53 | __ctl_set_bit(0, 9); | ||
54 | rc = sclp_service_call(cmd, sccb); | ||
55 | if (rc) | ||
56 | goto out; | ||
57 | __load_psw_mask(PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA | | ||
58 | PSW_MASK_BA | PSW_MASK_EXT | PSW_MASK_WAIT); | ||
59 | local_irq_disable(); | ||
60 | out: | ||
61 | /* Contents of the sccb might have changed. */ | ||
62 | barrier(); | ||
63 | __ctl_clear_bit(0, 9); | ||
64 | return rc; | ||
65 | } | ||
66 | |||
67 | static void __init sclp_read_info_early(void) | ||
68 | { | ||
69 | int rc; | ||
70 | int i; | ||
71 | struct read_info_sccb *sccb; | ||
72 | sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, | ||
73 | SCLP_CMDW_READ_SCP_INFO}; | ||
74 | |||
75 | sccb = &early_read_info_sccb; | ||
76 | for (i = 0; i < ARRAY_SIZE(commands); i++) { | ||
77 | do { | ||
78 | memset(sccb, 0, sizeof(*sccb)); | ||
79 | sccb->header.length = sizeof(*sccb); | ||
80 | sccb->header.function_code = 0x80; | ||
81 | sccb->header.control_mask[2] = 0x80; | ||
82 | rc = sclp_cmd_sync_early(commands[i], sccb); | ||
83 | } while (rc == -EBUSY); | ||
84 | |||
85 | if (rc) | ||
86 | break; | ||
87 | if (sccb->header.response_code == 0x10) { | ||
88 | sclp_early_read_info_sccb_valid = 1; | ||
89 | break; | ||
90 | } | ||
91 | if (sccb->header.response_code != 0x1f0) | ||
92 | break; | ||
93 | } | ||
94 | } | ||
95 | |||
96 | static void __init sclp_event_mask_early(void) | ||
97 | { | ||
98 | struct init_sccb *sccb = &early_event_mask_sccb; | ||
99 | int rc; | ||
100 | |||
101 | do { | ||
102 | memset(sccb, 0, sizeof(*sccb)); | ||
103 | sccb->header.length = sizeof(*sccb); | ||
104 | sccb->mask_length = sizeof(sccb_mask_t); | ||
105 | rc = sclp_cmd_sync_early(SCLP_CMDW_WRITE_EVENT_MASK, sccb); | ||
106 | } while (rc == -EBUSY); | ||
107 | } | ||
108 | |||
109 | void __init sclp_facilities_detect(void) | ||
110 | { | ||
111 | struct read_info_sccb *sccb; | ||
112 | |||
113 | sclp_read_info_early(); | ||
114 | if (!sclp_early_read_info_sccb_valid) | ||
115 | return; | ||
116 | |||
117 | sccb = &early_read_info_sccb; | ||
118 | sclp_facilities = sccb->facilities; | ||
119 | sclp_fac84 = sccb->fac84; | ||
120 | if (sccb->fac85 & 0x02) | ||
121 | S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP; | ||
122 | sclp_rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2; | ||
123 | sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2; | ||
124 | sclp_rzm <<= 20; | ||
125 | |||
126 | sclp_event_mask_early(); | ||
127 | } | ||
128 | |||
129 | bool __init sclp_has_linemode(void) | ||
130 | { | ||
131 | struct init_sccb *sccb = &early_event_mask_sccb; | ||
132 | |||
133 | if (sccb->header.response_code != 0x20) | ||
134 | return 0; | ||
135 | if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK))) | ||
136 | return 0; | ||
137 | if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK))) | ||
138 | return 0; | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | bool __init sclp_has_vt220(void) | ||
143 | { | ||
144 | struct init_sccb *sccb = &early_event_mask_sccb; | ||
145 | |||
146 | if (sccb->header.response_code != 0x20) | ||
147 | return 0; | ||
148 | if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK) | ||
149 | return 1; | ||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | unsigned long long sclp_get_rnmax(void) | ||
154 | { | ||
155 | return sclp_rnmax; | ||
156 | } | ||
157 | |||
158 | unsigned long long sclp_get_rzm(void) | ||
159 | { | ||
160 | return sclp_rzm; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * This function will be called after sclp_facilities_detect(), which gets | ||
165 | * called from early.c code. Therefore the sccb should have valid contents. | ||
166 | */ | ||
167 | void __init sclp_get_ipl_info(struct sclp_ipl_info *info) | ||
168 | { | ||
169 | struct read_info_sccb *sccb; | ||
170 | |||
171 | if (!sclp_early_read_info_sccb_valid) | ||
172 | return; | ||
173 | sccb = &early_read_info_sccb; | ||
174 | info->is_valid = 1; | ||
175 | if (sccb->flags & 0x2) | ||
176 | info->has_dump = 1; | ||
177 | memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN); | ||
178 | } | ||
179 | |||
18 | static int __init sclp_cmd_early(sclp_cmdw_t cmd, void *sccb) | 180 | static int __init sclp_cmd_early(sclp_cmdw_t cmd, void *sccb) |
19 | { | 181 | { |
20 | int rc; | 182 | int rc; |