aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/sclp_cmd.c
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2013-11-13 04:38:27 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-11-15 08:08:41 -0500
commitacf6a004e6a35dad17032e3b7c5a046c29957e65 (patch)
tree377fb42d62773abbb2bbddecdfff8b8e3eb8f3f8 /drivers/s390/char/sclp_cmd.c
parente657d8fe2faf49ed5d35e2325bd0f1712b8058cd (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>
Diffstat (limited to 'drivers/s390/char/sclp_cmd.c')
-rw-r--r--drivers/s390/char/sclp_cmd.c180
1 files changed, 9 insertions, 171 deletions
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
34struct 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
53static struct init_sccb __initdata early_event_mask_sccb __aligned(PAGE_SIZE);
54static struct read_info_sccb __initdata early_read_info_sccb;
55static int __initdata early_read_info_sccb_valid;
56
57u64 sclp_facilities;
58static u8 sclp_fac84;
59static unsigned long long rzm;
60static unsigned long long rnmax;
61
62int __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();
73out:
74 /* Contents of the sccb might have changed. */
75 barrier();
76 __ctl_clear_bit(0, 9);
77 return rc;
78}
79
80static 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
109static 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
122void __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
142bool __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
155bool __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
166unsigned long long sclp_get_rnmax(void)
167{
168 return rnmax;
169}
170
171unsigned 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 */
180void __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
193static void sclp_sync_callback(struct sclp_req *req, void *data) 31static 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
357int arch_get_memory_phys_device(unsigned long start_pfn) 195int 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
364static unsigned long long rn2addr(u16 rn) 202static 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
369static int do_assign_storage(sclp_cmdw_t cmd, u16 rn) 207static 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)