aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-02-22 13:20:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-02-22 13:20:04 -0500
commitff47d8c05019d6e7753cef270d6399cb5a33be57 (patch)
tree78eec48c53554902062f9a06b57a700d7671330e /drivers
parent3051bf36c25d5153051704291782f8d44e744d36 (diff)
parentd24b98e3a9c66b16ed029e1b2bcdf3c90e9d82d9 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky: - New entropy generation for the pseudo random number generator. - Early boot printk output via sclp to help debug crashes on boot. This needs to be enabled with a kernel parameter. - Add proper no-execute support with a bit in the page table entry. - Bug fixes and cleanups. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (65 commits) s390/syscall: fix single stepped system calls s390/zcrypt: make ap_bus explicitly non-modular s390/zcrypt: Removed unneeded debug feature directory creation. s390: add missing "do {} while (0)" loop constructs to multiline macros s390/mm: add cond_resched call to kernel page table dumper s390: get rid of MACHINE_HAS_PFMF and MACHINE_HAS_HPAGE s390/mm: make memory_block_size_bytes available for !MEMORY_HOTPLUG s390: replace ACCESS_ONCE with READ_ONCE s390: Audit and remove any remaining unnecessary uses of module.h s390: mm: Audit and remove any unnecessary uses of module.h s390: kernel: Audit and remove any unnecessary uses of module.h s390/kdump: Use "LINUX" ELF note name instead of "CORE" s390: add no-execute support s390: report new vector facilities s390: use correct input data address for setup_randomness s390/sclp: get rid of common response code handling s390/sclp: don't add new lines to each printed string s390/sclp: make early sclp code readable s390/sclp: disable early sclp code as soon as the base sclp driver is active s390/sclp: move early printk code to drivers ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/block/dasd.c16
-rw-r--r--drivers/s390/block/dasd_devmap.c294
-rw-r--r--drivers/s390/block/dasd_eckd.c4
-rw-r--r--drivers/s390/block/dasd_int.h2
-rw-r--r--drivers/s390/block/dcssblk.c2
-rw-r--r--drivers/s390/char/Makefile16
-rw-r--r--drivers/s390/char/con3270.c2
-rw-r--r--drivers/s390/char/raw3270.c2
-rw-r--r--drivers/s390/char/sclp.c32
-rw-r--r--drivers/s390/char/sclp.h40
-rw-r--r--drivers/s390/char/sclp_early.c201
-rw-r--r--drivers/s390/char/sclp_early_core.c208
-rw-r--r--drivers/s390/char/zcore.c3
-rw-r--r--drivers/s390/cio/chp.c13
-rw-r--r--drivers/s390/cio/chp.h2
-rw-r--r--drivers/s390/cio/chsc.c48
-rw-r--r--drivers/s390/cio/chsc.h2
-rw-r--r--drivers/s390/cio/cmf.c10
-rw-r--r--drivers/s390/cio/css.c209
-rw-r--r--drivers/s390/cio/css.h13
-rw-r--r--drivers/s390/cio/qdio_main.c5
-rw-r--r--drivers/s390/cio/qdio_thinint.c19
-rw-r--r--drivers/s390/crypto/ap_asm.h10
-rw-r--r--drivers/s390/crypto/ap_bus.c57
-rw-r--r--drivers/s390/crypto/ap_card.c2
-rw-r--r--drivers/s390/crypto/ap_queue.c2
-rw-r--r--drivers/s390/crypto/zcrypt_api.c15
-rw-r--r--drivers/s390/virtio/virtio_ccw.c2
28 files changed, 697 insertions, 534 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 0e3fdfdbd098..6fb3fd5efc11 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1712,8 +1712,11 @@ void dasd_int_handler(struct ccw_device *cdev, unsigned long intparm,
1712 /* check for for attention message */ 1712 /* check for for attention message */
1713 if (scsw_dstat(&irb->scsw) & DEV_STAT_ATTENTION) { 1713 if (scsw_dstat(&irb->scsw) & DEV_STAT_ATTENTION) {
1714 device = dasd_device_from_cdev_locked(cdev); 1714 device = dasd_device_from_cdev_locked(cdev);
1715 device->discipline->check_attention(device, irb->esw.esw1.lpum); 1715 if (!IS_ERR(device)) {
1716 dasd_put_device(device); 1716 device->discipline->check_attention(device,
1717 irb->esw.esw1.lpum);
1718 dasd_put_device(device);
1719 }
1717 } 1720 }
1718 1721
1719 if (!cqr) 1722 if (!cqr)
@@ -3598,10 +3601,11 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
3598 * empty 3601 * empty
3599 */ 3602 */
3600 /* sync blockdev and partitions */ 3603 /* sync blockdev and partitions */
3601 rc = fsync_bdev(device->block->bdev); 3604 if (device->block) {
3602 if (rc != 0) 3605 rc = fsync_bdev(device->block->bdev);
3603 goto interrupted; 3606 if (rc != 0)
3604 3607 goto interrupted;
3608 }
3605 /* schedule device tasklet and wait for completion */ 3609 /* schedule device tasklet and wait for completion */
3606 dasd_schedule_device_bh(device); 3610 dasd_schedule_device_bh(device);
3607 rc = wait_event_interruptible(shutdown_waitq, 3611 rc = wait_event_interruptible(shutdown_waitq,
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index dd46e96a3034..1164b51d09f3 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -26,6 +26,7 @@
26/* This is ugly... */ 26/* This is ugly... */
27#define PRINTK_HEADER "dasd_devmap:" 27#define PRINTK_HEADER "dasd_devmap:"
28#define DASD_BUS_ID_SIZE 20 28#define DASD_BUS_ID_SIZE 20
29#define DASD_MAX_PARAMS 256
29 30
30#include "dasd_int.h" 31#include "dasd_int.h"
31 32
@@ -76,7 +77,7 @@ EXPORT_SYMBOL_GPL(dasd_nofcx);
76 * it is named 'dasd' to directly be filled by insmod with the comma separated 77 * it is named 'dasd' to directly be filled by insmod with the comma separated
77 * strings when running as a module. 78 * strings when running as a module.
78 */ 79 */
79static char *dasd[256]; 80static char *dasd[DASD_MAX_PARAMS];
80module_param_array(dasd, charp, NULL, S_IRUGO); 81module_param_array(dasd, charp, NULL, S_IRUGO);
81 82
82/* 83/*
@@ -104,18 +105,19 @@ dasd_hash_busid(const char *bus_id)
104} 105}
105 106
106#ifndef MODULE 107#ifndef MODULE
107/* 108static int __init dasd_call_setup(char *opt)
108 * The parameter parsing functions for builtin-drivers are called
109 * before kmalloc works. Store the pointers to the parameters strings
110 * into dasd[] for later processing.
111 */
112static int __init
113dasd_call_setup(char *str)
114{ 109{
115 static int count = 0; 110 static int i __initdata;
111 char *tmp;
112
113 while (i < DASD_MAX_PARAMS) {
114 tmp = strsep(&opt, ",");
115 if (!tmp)
116 break;
117
118 dasd[i++] = tmp;
119 }
116 120
117 if (count < 256)
118 dasd[count++] = str;
119 return 1; 121 return 1;
120} 122}
121 123
@@ -127,14 +129,13 @@ __setup ("dasd=", dasd_call_setup);
127/* 129/*
128 * Read a device busid/devno from a string. 130 * Read a device busid/devno from a string.
129 */ 131 */
130static int 132static int __init dasd_busid(char *str, int *id0, int *id1, int *devno)
131
132dasd_busid(char **str, int *id0, int *id1, int *devno)
133{ 133{
134 int val, old_style; 134 unsigned int val;
135 char *tok;
135 136
136 /* Interpret ipldev busid */ 137 /* Interpret ipldev busid */
137 if (strncmp(DASD_IPLDEV, *str, strlen(DASD_IPLDEV)) == 0) { 138 if (strncmp(DASD_IPLDEV, str, strlen(DASD_IPLDEV)) == 0) {
138 if (ipl_info.type != IPL_TYPE_CCW) { 139 if (ipl_info.type != IPL_TYPE_CCW) {
139 pr_err("The IPL device is not a CCW device\n"); 140 pr_err("The IPL device is not a CCW device\n");
140 return -EINVAL; 141 return -EINVAL;
@@ -142,63 +143,50 @@ dasd_busid(char **str, int *id0, int *id1, int *devno)
142 *id0 = 0; 143 *id0 = 0;
143 *id1 = ipl_info.data.ccw.dev_id.ssid; 144 *id1 = ipl_info.data.ccw.dev_id.ssid;
144 *devno = ipl_info.data.ccw.dev_id.devno; 145 *devno = ipl_info.data.ccw.dev_id.devno;
145 *str += strlen(DASD_IPLDEV);
146 146
147 return 0; 147 return 0;
148 } 148 }
149 /* check for leading '0x' */ 149
150 old_style = 0; 150 /* Old style 0xXXXX or XXXX */
151 if ((*str)[0] == '0' && (*str)[1] == 'x') { 151 if (!kstrtouint(str, 16, &val)) {
152 *str += 2;
153 old_style = 1;
154 }
155 if (!isxdigit((*str)[0])) /* We require at least one hex digit */
156 return -EINVAL;
157 val = simple_strtoul(*str, str, 16);
158 if (old_style || (*str)[0] != '.') {
159 *id0 = *id1 = 0; 152 *id0 = *id1 = 0;
160 if (val < 0 || val > 0xffff) 153 if (val < 0 || val > 0xffff)
161 return -EINVAL; 154 return -EINVAL;
162 *devno = val; 155 *devno = val;
163 return 0; 156 return 0;
164 } 157 }
158
165 /* New style x.y.z busid */ 159 /* New style x.y.z busid */
166 if (val < 0 || val > 0xff) 160 tok = strsep(&str, ".");
161 if (kstrtouint(tok, 16, &val) || val > 0xff)
167 return -EINVAL; 162 return -EINVAL;
168 *id0 = val; 163 *id0 = val;
169 (*str)++; 164
170 if (!isxdigit((*str)[0])) /* We require at least one hex digit */ 165 tok = strsep(&str, ".");
171 return -EINVAL; 166 if (kstrtouint(tok, 16, &val) || val > 0xff)
172 val = simple_strtoul(*str, str, 16);
173 if (val < 0 || val > 0xff || (*str)++[0] != '.')
174 return -EINVAL; 167 return -EINVAL;
175 *id1 = val; 168 *id1 = val;
176 if (!isxdigit((*str)[0])) /* We require at least one hex digit */ 169
177 return -EINVAL; 170 tok = strsep(&str, ".");
178 val = simple_strtoul(*str, str, 16); 171 if (kstrtouint(tok, 16, &val) || val > 0xffff)
179 if (val < 0 || val > 0xffff)
180 return -EINVAL; 172 return -EINVAL;
181 *devno = val; 173 *devno = val;
174
182 return 0; 175 return 0;
183} 176}
184 177
185/* 178/*
186 * Read colon separated list of dasd features. Currently there is 179 * Read colon separated list of dasd features.
187 * only one: "ro" for read-only devices. The default feature set
188 * is empty (value 0).
189 */ 180 */
190static int 181static int __init dasd_feature_list(char *str)
191dasd_feature_list(char *str, char **endp)
192{ 182{
193 int features, len, rc; 183 int features, len, rc;
194 184
185 features = 0;
195 rc = 0; 186 rc = 0;
196 if (*str != '(') { 187
197 *endp = str; 188 if (!str)
198 return DASD_FEATURE_DEFAULT; 189 return DASD_FEATURE_DEFAULT;
199 }
200 str++;
201 features = 0;
202 190
203 while (1) { 191 while (1) {
204 for (len = 0; 192 for (len = 0;
@@ -223,15 +211,8 @@ dasd_feature_list(char *str, char **endp)
223 break; 211 break;
224 str++; 212 str++;
225 } 213 }
226 if (*str != ')') { 214
227 pr_warn("A closing parenthesis ')' is missing in the dasd= parameter\n"); 215 return rc ? : features;
228 rc = -EINVAL;
229 } else
230 str++;
231 *endp = str;
232 if (rc != 0)
233 return rc;
234 return features;
235} 216}
236 217
237/* 218/*
@@ -240,48 +221,38 @@ dasd_feature_list(char *str, char **endp)
240 * action and return a pointer to the residual string. If the first element 221 * action and return a pointer to the residual string. If the first element
241 * could not be matched to any keyword then return an error code. 222 * could not be matched to any keyword then return an error code.
242 */ 223 */
243static char * 224static int __init dasd_parse_keyword(char *keyword)
244dasd_parse_keyword( char *parsestring ) { 225{
245 226 int length = strlen(keyword);
246 char *nextcomma, *residual_str;
247 int length;
248 227
249 nextcomma = strchr(parsestring,','); 228 if (strncmp("autodetect", keyword, length) == 0) {
250 if (nextcomma) {
251 length = nextcomma - parsestring;
252 residual_str = nextcomma + 1;
253 } else {
254 length = strlen(parsestring);
255 residual_str = parsestring + length;
256 }
257 if (strncmp("autodetect", parsestring, length) == 0) {
258 dasd_autodetect = 1; 229 dasd_autodetect = 1;
259 pr_info("The autodetection mode has been activated\n"); 230 pr_info("The autodetection mode has been activated\n");
260 return residual_str; 231 return 0;
261 } 232 }
262 if (strncmp("probeonly", parsestring, length) == 0) { 233 if (strncmp("probeonly", keyword, length) == 0) {
263 dasd_probeonly = 1; 234 dasd_probeonly = 1;
264 pr_info("The probeonly mode has been activated\n"); 235 pr_info("The probeonly mode has been activated\n");
265 return residual_str; 236 return 0;
266 } 237 }
267 if (strncmp("nopav", parsestring, length) == 0) { 238 if (strncmp("nopav", keyword, length) == 0) {
268 if (MACHINE_IS_VM) 239 if (MACHINE_IS_VM)
269 pr_info("'nopav' is not supported on z/VM\n"); 240 pr_info("'nopav' is not supported on z/VM\n");
270 else { 241 else {
271 dasd_nopav = 1; 242 dasd_nopav = 1;
272 pr_info("PAV support has be deactivated\n"); 243 pr_info("PAV support has be deactivated\n");
273 } 244 }
274 return residual_str; 245 return 0;
275 } 246 }
276 if (strncmp("nofcx", parsestring, length) == 0) { 247 if (strncmp("nofcx", keyword, length) == 0) {
277 dasd_nofcx = 1; 248 dasd_nofcx = 1;
278 pr_info("High Performance FICON support has been " 249 pr_info("High Performance FICON support has been "
279 "deactivated\n"); 250 "deactivated\n");
280 return residual_str; 251 return 0;
281 } 252 }
282 if (strncmp("fixedbuffers", parsestring, length) == 0) { 253 if (strncmp("fixedbuffers", keyword, length) == 0) {
283 if (dasd_page_cache) 254 if (dasd_page_cache)
284 return residual_str; 255 return 0;
285 dasd_page_cache = 256 dasd_page_cache =
286 kmem_cache_create("dasd_page_cache", PAGE_SIZE, 257 kmem_cache_create("dasd_page_cache", PAGE_SIZE,
287 PAGE_SIZE, SLAB_CACHE_DMA, 258 PAGE_SIZE, SLAB_CACHE_DMA,
@@ -292,107 +263,126 @@ dasd_parse_keyword( char *parsestring ) {
292 else 263 else
293 DBF_EVENT(DBF_INFO, "%s", 264 DBF_EVENT(DBF_INFO, "%s",
294 "turning on fixed buffer mode"); 265 "turning on fixed buffer mode");
295 return residual_str; 266 return 0;
296 } 267 }
297 return ERR_PTR(-EINVAL); 268
269 return -EINVAL;
298} 270}
299 271
300/* 272/*
301 * Try to interprete the first element on the comma separated parse string 273 * Split a string of a device range into its pieces and return the from, to, and
302 * as a device number or a range of devices. If the interpretation is 274 * feature parts separately.
303 * successful, create the matching dasd_devmap entries and return a pointer 275 * e.g.:
304 * to the residual string. 276 * 0.0.1234-0.0.5678(ro:erplog) -> from: 0.0.1234 to: 0.0.5678 features: ro:erplog
305 * If interpretation fails or in case of an error, return an error code. 277 * 0.0.8765(raw) -> from: 0.0.8765 to: null features: raw
278 * 0x4321 -> from: 0x4321 to: null features: null
306 */ 279 */
307static char * 280static int __init dasd_evaluate_range_param(char *range, char **from_str,
308dasd_parse_range( char *parsestring ) { 281 char **to_str, char **features_str)
282{
283 int rc = 0;
284
285 /* Do we have a range or a single device? */
286 if (strchr(range, '-')) {
287 *from_str = strsep(&range, "-");
288 *to_str = strsep(&range, "(");
289 *features_str = strsep(&range, ")");
290 } else {
291 *from_str = strsep(&range, "(");
292 *features_str = strsep(&range, ")");
293 }
309 294
295 if (*features_str && !range) {
296 pr_warn("A closing parenthesis ')' is missing in the dasd= parameter\n");
297 rc = -EINVAL;
298 }
299
300 return rc;
301}
302
303/*
304 * Try to interprete the range string as a device number or a range of devices.
305 * If the interpretation is successful, create the matching dasd_devmap entries.
306 * If interpretation fails or in case of an error, return an error code.
307 */
308static int __init dasd_parse_range(const char *range)
309{
310 struct dasd_devmap *devmap; 310 struct dasd_devmap *devmap;
311 int from, from_id0, from_id1; 311 int from, from_id0, from_id1;
312 int to, to_id0, to_id1; 312 int to, to_id0, to_id1;
313 int features, rc; 313 int features;
314 char bus_id[DASD_BUS_ID_SIZE+1], *str; 314 char bus_id[DASD_BUS_ID_SIZE + 1];
315 315 char *features_str = NULL;
316 str = parsestring; 316 char *from_str = NULL;
317 rc = dasd_busid(&str, &from_id0, &from_id1, &from); 317 char *to_str = NULL;
318 if (rc == 0) { 318 size_t len = strlen(range) + 1;
319 to = from; 319 char tmp[len];
320 to_id0 = from_id0; 320
321 to_id1 = from_id1; 321 strlcpy(tmp, range, len);
322 if (*str == '-') { 322
323 str++; 323 if (dasd_evaluate_range_param(tmp, &from_str, &to_str, &features_str))
324 rc = dasd_busid(&str, &to_id0, &to_id1, &to); 324 goto out_err;
325
326 if (dasd_busid(from_str, &from_id0, &from_id1, &from))
327 goto out_err;
328
329 to = from;
330 to_id0 = from_id0;
331 to_id1 = from_id1;
332 if (to_str) {
333 if (dasd_busid(to_str, &to_id0, &to_id1, &to))
334 goto out_err;
335 if (from_id0 != to_id0 || from_id1 != to_id1 || from > to) {
336 pr_err("%s is not a valid device range\n", range);
337 goto out_err;
325 } 338 }
326 } 339 }
327 if (rc == 0 && 340
328 (from_id0 != to_id0 || from_id1 != to_id1 || from > to)) 341 features = dasd_feature_list(features_str);
329 rc = -EINVAL;
330 if (rc) {
331 pr_err("%s is not a valid device range\n", parsestring);
332 return ERR_PTR(rc);
333 }
334 features = dasd_feature_list(str, &str);
335 if (features < 0) 342 if (features < 0)
336 return ERR_PTR(-EINVAL); 343 goto out_err;
337 /* each device in dasd= parameter should be set initially online */ 344 /* each device in dasd= parameter should be set initially online */
338 features |= DASD_FEATURE_INITIAL_ONLINE; 345 features |= DASD_FEATURE_INITIAL_ONLINE;
339 while (from <= to) { 346 while (from <= to) {
340 sprintf(bus_id, "%01x.%01x.%04x", 347 sprintf(bus_id, "%01x.%01x.%04x", from_id0, from_id1, from++);
341 from_id0, from_id1, from++);
342 devmap = dasd_add_busid(bus_id, features); 348 devmap = dasd_add_busid(bus_id, features);
343 if (IS_ERR(devmap)) 349 if (IS_ERR(devmap))
344 return (char *)devmap; 350 return PTR_ERR(devmap);
345 } 351 }
346 if (*str == ',')
347 return str + 1;
348 if (*str == '\0')
349 return str;
350 pr_warn("The dasd= parameter value %s has an invalid ending\n", str);
351 return ERR_PTR(-EINVAL);
352}
353 352
354static char * 353 return 0;
355dasd_parse_next_element( char *parsestring ) { 354
356 char * residual_str; 355out_err:
357 residual_str = dasd_parse_keyword(parsestring); 356 return -EINVAL;
358 if (!IS_ERR(residual_str))
359 return residual_str;
360 residual_str = dasd_parse_range(parsestring);
361 return residual_str;
362} 357}
363 358
364/* 359/*
365 * Parse parameters stored in dasd[] 360 * Parse parameters stored in dasd[]
366 * The 'dasd=...' parameter allows to specify a comma separated list of 361 * The 'dasd=...' parameter allows to specify a comma separated list of
367 * keywords and device ranges. When the dasd driver is build into the kernel, 362 * keywords and device ranges. The parameters in that list will be stored as
368 * the complete list will be stored as one element of the dasd[] array. 363 * separate elementes in dasd[].
369 * When the dasd driver is build as a module, then the list is broken into
370 * it's elements and each dasd[] entry contains one element.
371 */ 364 */
372int 365int __init dasd_parse(void)
373dasd_parse(void)
374{ 366{
375 int rc, i; 367 int rc, i;
376 char *parsestring; 368 char *cur;
377 369
378 rc = 0; 370 rc = 0;
379 for (i = 0; i < 256; i++) { 371 for (i = 0; i < DASD_MAX_PARAMS; i++) {
380 if (dasd[i] == NULL) 372 cur = dasd[i];
373 if (!cur)
381 break; 374 break;
382 parsestring = dasd[i]; 375 if (*cur == '\0')
383 /* loop over the comma separated list in the parsestring */ 376 continue;
384 while (*parsestring) { 377
385 parsestring = dasd_parse_next_element(parsestring); 378 rc = dasd_parse_keyword(cur);
386 if(IS_ERR(parsestring)) { 379 if (rc)
387 rc = PTR_ERR(parsestring); 380 rc = dasd_parse_range(cur);
388 break; 381
389 } 382 if (rc)
390 }
391 if (rc) {
392 DBF_EVENT(DBF_ALERT, "%s", "invalid range found");
393 break; 383 break;
394 }
395 } 384 }
385
396 return rc; 386 return rc;
397} 387}
398 388
@@ -1528,14 +1518,12 @@ dasd_path_threshold_store(struct device *dev, struct device_attribute *attr,
1528 if (IS_ERR(device)) 1518 if (IS_ERR(device))
1529 return -ENODEV; 1519 return -ENODEV;
1530 1520
1531 if ((kstrtoul(buf, 10, &val) != 0) || 1521 if (kstrtoul(buf, 10, &val) != 0 || val > DASD_THRHLD_MAX) {
1532 (val > DASD_THRHLD_MAX) || val == 0) {
1533 dasd_put_device(device); 1522 dasd_put_device(device);
1534 return -EINVAL; 1523 return -EINVAL;
1535 } 1524 }
1536 spin_lock_irqsave(get_ccwdev_lock(to_ccwdev(dev)), flags); 1525 spin_lock_irqsave(get_ccwdev_lock(to_ccwdev(dev)), flags);
1537 if (val) 1526 device->path_thrhld = val;
1538 device->path_thrhld = val;
1539 spin_unlock_irqrestore(get_ccwdev_lock(to_ccwdev(dev)), flags); 1527 spin_unlock_irqrestore(get_ccwdev_lock(to_ccwdev(dev)), flags);
1540 dasd_put_device(device); 1528 dasd_put_device(device);
1541 return count; 1529 return count;
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index ade04216c970..0f1713727d4c 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -2543,8 +2543,8 @@ dasd_eckd_build_format(struct dasd_device *base,
2543 DASD_ECKD_CCW_WRITE_CKD_MT; 2543 DASD_ECKD_CCW_WRITE_CKD_MT;
2544 ccw->flags = CCW_FLAG_SLI; 2544 ccw->flags = CCW_FLAG_SLI;
2545 ccw->count = 8; 2545 ccw->count = 8;
2546 ccw->cda = (__u32)(addr_t) ect; 2546 ccw->cda = (__u32)(addr_t) ect;
2547 ccw++; 2547 ccw++;
2548 } 2548 }
2549 } 2549 }
2550 } 2550 }
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 24be210c10e5..518dba2732d5 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -805,7 +805,7 @@ struct dasd_device *dasd_device_from_devindex(int);
805void dasd_add_link_to_gendisk(struct gendisk *, struct dasd_device *); 805void dasd_add_link_to_gendisk(struct gendisk *, struct dasd_device *);
806struct dasd_device *dasd_device_from_gendisk(struct gendisk *); 806struct dasd_device *dasd_device_from_gendisk(struct gendisk *);
807 807
808int dasd_parse(void); 808int dasd_parse(void) __init;
809int dasd_busid_known(const char *); 809int dasd_busid_known(const char *);
810 810
811/* externals in dasd_gendisk.c */ 811/* externals in dasd_gendisk.c */
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index 9d66b4fb174b..415d10a67b7a 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -892,7 +892,7 @@ dcssblk_direct_access (struct block_device *bdev, sector_t secnum,
892 dev_info = bdev->bd_disk->private_data; 892 dev_info = bdev->bd_disk->private_data;
893 if (!dev_info) 893 if (!dev_info)
894 return -ENODEV; 894 return -ENODEV;
895 dev_sz = dev_info->end - dev_info->start; 895 dev_sz = dev_info->end - dev_info->start + 1;
896 offset = secnum * 512; 896 offset = secnum * 512;
897 *kaddr = (void *) dev_info->start + offset; 897 *kaddr = (void *) dev_info->start + offset;
898 *pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV); 898 *pfn = __pfn_to_pfn_t(PFN_DOWN(dev_info->start + offset), PFN_DEV);
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index 41e28b23b26a..0c443e26835d 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -2,9 +2,23 @@
2# S/390 character devices 2# S/390 character devices
3# 3#
4 4
5ifdef CONFIG_FUNCTION_TRACER
6# Do not trace early setup code
7CFLAGS_REMOVE_sclp_early_core.o = $(CC_FLAGS_FTRACE)
8endif
9
10GCOV_PROFILE_sclp_early_core.o := n
11KCOV_INSTRUMENT_sclp_early_core.o := n
12UBSAN_SANITIZE_sclp_early_core.o := n
13
14ifneq ($(CC_FLAGS_MARCH),-march=z900)
15CFLAGS_REMOVE_sclp_early_core.o += $(CC_FLAGS_MARCH)
16CFLAGS_sclp_early_core.o += -march=z900
17endif
18
5obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \ 19obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \
6 sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o sclp_ctl.o \ 20 sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o sclp_ctl.o \
7 sclp_early.o 21 sclp_early.o sclp_early_core.o
8 22
9obj-$(CONFIG_TN3270) += raw3270.o 23obj-$(CONFIG_TN3270) += raw3270.o
10obj-$(CONFIG_TN3270_CONSOLE) += con3270.o 24obj-$(CONFIG_TN3270_CONSOLE) += con3270.o
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
index 285b4006f44b..8522cfce5b4e 100644
--- a/drivers/s390/char/con3270.c
+++ b/drivers/s390/char/con3270.c
@@ -31,7 +31,7 @@
31 31
32static struct raw3270_fn con3270_fn; 32static struct raw3270_fn con3270_fn;
33 33
34static bool auto_update = 1; 34static bool auto_update = true;
35module_param(auto_update, bool, 0); 35module_param(auto_update, bool, 0);
36 36
37/* 37/*
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index a2da898ce90f..710f2292911d 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -82,7 +82,7 @@ static LIST_HEAD(raw3270_devices);
82static int raw3270_registered; 82static int raw3270_registered;
83 83
84/* Module parameters */ 84/* Module parameters */
85static bool tubxcorrect = 0; 85static bool tubxcorrect;
86module_param(tubxcorrect, bool, 0); 86module_param(tubxcorrect, bool, 0);
87 87
88/* 88/*
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 272898225dbb..9c471ea1b99c 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -94,13 +94,6 @@ static struct timer_list sclp_request_timer;
94/* Timer for queued requests. */ 94/* Timer for queued requests. */
95static struct timer_list sclp_queue_timer; 95static struct timer_list sclp_queue_timer;
96 96
97/* Internal state: is the driver initialized? */
98static volatile enum sclp_init_state_t {
99 sclp_init_state_uninitialized,
100 sclp_init_state_initializing,
101 sclp_init_state_initialized
102} sclp_init_state = sclp_init_state_uninitialized;
103
104/* Internal state: is a request active at the sclp? */ 97/* Internal state: is a request active at the sclp? */
105static volatile enum sclp_running_state_t { 98static volatile enum sclp_running_state_t {
106 sclp_running_state_idle, 99 sclp_running_state_idle,
@@ -147,31 +140,6 @@ static void __sclp_make_read_req(void);
147static int sclp_init_mask(int calculate); 140static int sclp_init_mask(int calculate);
148static int sclp_init(void); 141static int sclp_init(void);
149 142
150/* Perform service call. Return 0 on success, non-zero otherwise. */
151int
152sclp_service_call(sclp_cmdw_t command, void *sccb)
153{
154 int cc = 4; /* Initialize for program check handling */
155
156 asm volatile(
157 "0: .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
158 "1: ipm %0\n"
159 " srl %0,28\n"
160 "2:\n"
161 EX_TABLE(0b, 2b)
162 EX_TABLE(1b, 2b)
163 : "+&d" (cc) : "d" (command), "a" (__pa(sccb))
164 : "cc", "memory");
165 if (cc == 4)
166 return -EINVAL;
167 if (cc == 3)
168 return -EIO;
169 if (cc == 2)
170 return -EBUSY;
171 return 0;
172}
173
174
175static void 143static void
176__sclp_queue_read_req(void) 144__sclp_queue_read_req(void)
177{ 145{
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index e1fc7eb043d6..53b5d1b9761a 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -204,19 +204,57 @@ void sclp_unregister(struct sclp_register *reg);
204int sclp_remove_processed(struct sccb_header *sccb); 204int sclp_remove_processed(struct sccb_header *sccb);
205int sclp_deactivate(void); 205int sclp_deactivate(void);
206int sclp_reactivate(void); 206int sclp_reactivate(void);
207int sclp_service_call(sclp_cmdw_t command, void *sccb);
208int sclp_sync_request(sclp_cmdw_t command, void *sccb); 207int sclp_sync_request(sclp_cmdw_t command, void *sccb);
209int sclp_sync_request_timeout(sclp_cmdw_t command, void *sccb, int timeout); 208int sclp_sync_request_timeout(sclp_cmdw_t command, void *sccb, int timeout);
210 209
211int sclp_sdias_init(void); 210int sclp_sdias_init(void);
212void sclp_sdias_exit(void); 211void sclp_sdias_exit(void);
213 212
213enum {
214 sclp_init_state_uninitialized,
215 sclp_init_state_initializing,
216 sclp_init_state_initialized
217};
218
219extern int sclp_init_state;
214extern int sclp_console_pages; 220extern int sclp_console_pages;
215extern int sclp_console_drop; 221extern int sclp_console_drop;
216extern unsigned long sclp_console_full; 222extern unsigned long sclp_console_full;
217 223
224extern char sclp_early_sccb[PAGE_SIZE];
225
226void sclp_early_wait_irq(void);
227int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb);
228unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb);
229int sclp_early_set_event_mask(struct init_sccb *sccb,
230 unsigned long receive_mask,
231 unsigned long send_mask);
232
218/* useful inlines */ 233/* useful inlines */
219 234
235/* Perform service call. Return 0 on success, non-zero otherwise. */
236static inline int sclp_service_call(sclp_cmdw_t command, void *sccb)
237{
238 int cc = 4; /* Initialize for program check handling */
239
240 asm volatile(
241 "0: .insn rre,0xb2200000,%1,%2\n" /* servc %1,%2 */
242 "1: ipm %0\n"
243 " srl %0,28\n"
244 "2:\n"
245 EX_TABLE(0b, 2b)
246 EX_TABLE(1b, 2b)
247 : "+&d" (cc) : "d" (command), "a" ((unsigned long)sccb)
248 : "cc", "memory");
249 if (cc == 4)
250 return -EINVAL;
251 if (cc == 3)
252 return -EIO;
253 if (cc == 2)
254 return -EBUSY;
255 return 0;
256}
257
220/* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */ 258/* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */
221/* translate single character from ASCII to EBCDIC */ 259/* translate single character from ASCII to EBCDIC */
222static inline unsigned char 260static inline unsigned char
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c
index f8e46c22e641..519ec1787117 100644
--- a/drivers/s390/char/sclp_early.c
+++ b/drivers/s390/char/sclp_early.c
@@ -55,46 +55,23 @@ struct read_info_sccb {
55 u8 _pad_128[4096 - 128]; /* 128-4095 */ 55 u8 _pad_128[4096 - 128]; /* 128-4095 */
56} __packed __aligned(PAGE_SIZE); 56} __packed __aligned(PAGE_SIZE);
57 57
58static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata;
59static struct sclp_ipl_info sclp_ipl_info; 58static struct sclp_ipl_info sclp_ipl_info;
60 59
61struct sclp_info sclp; 60struct sclp_info sclp;
62EXPORT_SYMBOL(sclp); 61EXPORT_SYMBOL(sclp);
63 62
64static int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb) 63static int __init sclp_early_read_info(struct read_info_sccb *sccb)
65{ 64{
66 int rc; 65 int i;
67
68 __ctl_set_bit(0, 9);
69 rc = sclp_service_call(cmd, sccb);
70 if (rc)
71 goto out;
72 __load_psw_mask(PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA |
73 PSW_MASK_BA | PSW_MASK_EXT | PSW_MASK_WAIT);
74 local_irq_disable();
75out:
76 /* Contents of the sccb might have changed. */
77 barrier();
78 __ctl_clear_bit(0, 9);
79 return rc;
80}
81
82static int __init sclp_read_info_early(struct read_info_sccb *sccb)
83{
84 int rc, i;
85 sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED, 66 sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
86 SCLP_CMDW_READ_SCP_INFO}; 67 SCLP_CMDW_READ_SCP_INFO};
87 68
88 for (i = 0; i < ARRAY_SIZE(commands); i++) { 69 for (i = 0; i < ARRAY_SIZE(commands); i++) {
89 do { 70 memset(sccb, 0, sizeof(*sccb));
90 memset(sccb, 0, sizeof(*sccb)); 71 sccb->header.length = sizeof(*sccb);
91 sccb->header.length = sizeof(*sccb); 72 sccb->header.function_code = 0x80;
92 sccb->header.function_code = 0x80; 73 sccb->header.control_mask[2] = 0x80;
93 sccb->header.control_mask[2] = 0x80; 74 if (sclp_early_cmd(commands[i], sccb))
94 rc = sclp_cmd_sync_early(commands[i], sccb);
95 } while (rc == -EBUSY);
96
97 if (rc)
98 break; 75 break;
99 if (sccb->header.response_code == 0x10) 76 if (sccb->header.response_code == 0x10)
100 return 0; 77 return 0;
@@ -104,12 +81,12 @@ static int __init sclp_read_info_early(struct read_info_sccb *sccb)
104 return -EIO; 81 return -EIO;
105} 82}
106 83
107static void __init sclp_facilities_detect(struct read_info_sccb *sccb) 84static void __init sclp_early_facilities_detect(struct read_info_sccb *sccb)
108{ 85{
109 struct sclp_core_entry *cpue; 86 struct sclp_core_entry *cpue;
110 u16 boot_cpu_address, cpu; 87 u16 boot_cpu_address, cpu;
111 88
112 if (sclp_read_info_early(sccb)) 89 if (sclp_early_read_info(sccb))
113 return; 90 return;
114 91
115 sclp.facilities = sccb->facilities; 92 sclp.facilities = sccb->facilities;
@@ -172,141 +149,96 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb)
172} 149}
173 150
174/* 151/*
175 * This function will be called after sclp_facilities_detect(), which gets 152 * This function will be called after sclp_early_facilities_detect(), which gets
176 * called from early.c code. The sclp_facilities_detect() function retrieves 153 * called from early.c code. The sclp_early_facilities_detect() function retrieves
177 * and saves the IPL information. 154 * and saves the IPL information.
178 */ 155 */
179void __init sclp_get_ipl_info(struct sclp_ipl_info *info) 156void __init sclp_early_get_ipl_info(struct sclp_ipl_info *info)
180{ 157{
181 *info = sclp_ipl_info; 158 *info = sclp_ipl_info;
182} 159}
183 160
184static int __init sclp_cmd_early(sclp_cmdw_t cmd, void *sccb) 161static struct sclp_core_info sclp_early_core_info __initdata;
185{ 162static int sclp_early_core_info_valid __initdata;
186 int rc;
187
188 do {
189 rc = sclp_cmd_sync_early(cmd, sccb);
190 } while (rc == -EBUSY);
191
192 if (rc)
193 return -EIO;
194 if (((struct sccb_header *) sccb)->response_code != 0x0020)
195 return -EIO;
196 return 0;
197}
198
199static void __init sccb_init_eq_size(struct sdias_sccb *sccb)
200{
201 memset(sccb, 0, sizeof(*sccb));
202
203 sccb->hdr.length = sizeof(*sccb);
204 sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf);
205 sccb->evbuf.hdr.type = EVTYP_SDIAS;
206 sccb->evbuf.event_qual = SDIAS_EQ_SIZE;
207 sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP;
208 sccb->evbuf.event_id = 4712;
209 sccb->evbuf.dbs = 1;
210}
211 163
212static int __init sclp_set_event_mask(struct init_sccb *sccb, 164static void __init sclp_early_init_core_info(struct read_cpu_info_sccb *sccb)
213 unsigned long receive_mask,
214 unsigned long send_mask)
215{ 165{
216 memset(sccb, 0, sizeof(*sccb));
217 sccb->header.length = sizeof(*sccb);
218 sccb->mask_length = sizeof(sccb_mask_t);
219 sccb->receive_mask = receive_mask;
220 sccb->send_mask = send_mask;
221 return sclp_cmd_early(SCLP_CMDW_WRITE_EVENT_MASK, sccb);
222}
223
224static struct sclp_core_info sclp_core_info_early __initdata;
225static int sclp_core_info_early_valid __initdata;
226
227static void __init sclp_init_core_info_early(struct read_cpu_info_sccb *sccb)
228{
229 int rc;
230
231 if (!SCLP_HAS_CPU_INFO) 166 if (!SCLP_HAS_CPU_INFO)
232 return; 167 return;
233 memset(sccb, 0, sizeof(*sccb)); 168 memset(sccb, 0, sizeof(*sccb));
234 sccb->header.length = sizeof(*sccb); 169 sccb->header.length = sizeof(*sccb);
235 do { 170 if (sclp_early_cmd(SCLP_CMDW_READ_CPU_INFO, sccb))
236 rc = sclp_cmd_sync_early(SCLP_CMDW_READ_CPU_INFO, sccb);
237 } while (rc == -EBUSY);
238 if (rc)
239 return; 171 return;
240 if (sccb->header.response_code != 0x0010) 172 if (sccb->header.response_code != 0x0010)
241 return; 173 return;
242 sclp_fill_core_info(&sclp_core_info_early, sccb); 174 sclp_fill_core_info(&sclp_early_core_info, sccb);
243 sclp_core_info_early_valid = 1; 175 sclp_early_core_info_valid = 1;
244} 176}
245 177
246int __init _sclp_get_core_info_early(struct sclp_core_info *info) 178int __init sclp_early_get_core_info(struct sclp_core_info *info)
247{ 179{
248 if (!sclp_core_info_early_valid) 180 if (!sclp_early_core_info_valid)
249 return -EIO; 181 return -EIO;
250 *info = sclp_core_info_early; 182 *info = sclp_early_core_info;
251 return 0; 183 return 0;
252} 184}
253 185
254static long __init sclp_hsa_size_init(struct sdias_sccb *sccb) 186static long __init sclp_early_hsa_size_init(struct sdias_sccb *sccb)
255{ 187{
256 sccb_init_eq_size(sccb); 188 memset(sccb, 0, sizeof(*sccb));
257 if (sclp_cmd_early(SCLP_CMDW_WRITE_EVENT_DATA, sccb)) 189 sccb->hdr.length = sizeof(*sccb);
190 sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf);
191 sccb->evbuf.hdr.type = EVTYP_SDIAS;
192 sccb->evbuf.event_qual = SDIAS_EQ_SIZE;
193 sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP;
194 sccb->evbuf.event_id = 4712;
195 sccb->evbuf.dbs = 1;
196 if (sclp_early_cmd(SCLP_CMDW_WRITE_EVENT_DATA, sccb))
197 return -EIO;
198 if (sccb->hdr.response_code != 0x20)
258 return -EIO; 199 return -EIO;
259 if (sccb->evbuf.blk_cnt == 0) 200 if (sccb->evbuf.blk_cnt == 0)
260 return 0; 201 return 0;
261 return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE; 202 return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE;
262} 203}
263 204
264static long __init sclp_hsa_copy_wait(struct sccb_header *sccb) 205static long __init sclp_early_hsa_copy_wait(struct sdias_sccb *sccb)
265{ 206{
266 memset(sccb, 0, PAGE_SIZE); 207 memset(sccb, 0, PAGE_SIZE);
267 sccb->length = PAGE_SIZE; 208 sccb->hdr.length = PAGE_SIZE;
268 if (sclp_cmd_early(SCLP_CMDW_READ_EVENT_DATA, sccb)) 209 if (sclp_early_cmd(SCLP_CMDW_READ_EVENT_DATA, sccb))
269 return -EIO; 210 return -EIO;
270 if (((struct sdias_sccb *) sccb)->evbuf.blk_cnt == 0) 211 if ((sccb->hdr.response_code != 0x20) && (sccb->hdr.response_code != 0x220))
212 return -EIO;
213 if (sccb->evbuf.blk_cnt == 0)
271 return 0; 214 return 0;
272 return (((struct sdias_sccb *) sccb)->evbuf.blk_cnt - 1) * PAGE_SIZE; 215 return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE;
273} 216}
274 217
275static void __init sclp_hsa_size_detect(void *sccb) 218static void __init sclp_early_hsa_size_detect(void *sccb)
276{ 219{
277 long size; 220 unsigned long flags;
221 long size = -EIO;
278 222
279 /* First try synchronous interface (LPAR) */ 223 raw_local_irq_save(flags);
280 if (sclp_set_event_mask(sccb, 0, 0x40000010)) 224 if (sclp_early_set_event_mask(sccb, EVTYP_SDIAS_MASK, EVTYP_SDIAS_MASK))
281 return;
282 size = sclp_hsa_size_init(sccb);
283 if (size < 0)
284 return;
285 if (size != 0)
286 goto out; 225 goto out;
287 /* Then try asynchronous interface (z/VM) */ 226 size = sclp_early_hsa_size_init(sccb);
288 if (sclp_set_event_mask(sccb, 0x00000010, 0x40000010)) 227 /* First check for synchronous response (LPAR) */
289 return; 228 if (size)
290 size = sclp_hsa_size_init(sccb); 229 goto out_mask;
291 if (size < 0) 230 if (!(S390_lowcore.ext_params & 1))
292 return; 231 sclp_early_wait_irq();
293 size = sclp_hsa_copy_wait(sccb); 232 size = sclp_early_hsa_copy_wait(sccb);
294 if (size < 0) 233out_mask:
295 return; 234 sclp_early_set_event_mask(sccb, 0, 0);
296out: 235out:
297 sclp.hsa_size = size; 236 raw_local_irq_restore(flags);
298} 237 if (size > 0)
299 238 sclp.hsa_size = size;
300static unsigned int __init sclp_con_check_linemode(struct init_sccb *sccb)
301{
302 if (!(sccb->sclp_send_mask & EVTYP_OPCMD_MASK))
303 return 0;
304 if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
305 return 0;
306 return 1;
307} 239}
308 240
309static void __init sclp_console_detect(struct init_sccb *sccb) 241static void __init sclp_early_console_detect(struct init_sccb *sccb)
310{ 242{
311 if (sccb->header.response_code != 0x20) 243 if (sccb->header.response_code != 0x20)
312 return; 244 return;
@@ -314,21 +246,22 @@ static void __init sclp_console_detect(struct init_sccb *sccb)
314 if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK) 246 if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK)
315 sclp.has_vt220 = 1; 247 sclp.has_vt220 = 1;
316 248
317 if (sclp_con_check_linemode(sccb)) 249 if (sclp_early_con_check_linemode(sccb))
318 sclp.has_linemode = 1; 250 sclp.has_linemode = 1;
319} 251}
320 252
321void __init sclp_early_detect(void) 253void __init sclp_early_detect(void)
322{ 254{
323 void *sccb = &sccb_early; 255 void *sccb = &sclp_early_sccb;
324 256
325 sclp_facilities_detect(sccb); 257 sclp_early_facilities_detect(sccb);
326 sclp_init_core_info_early(sccb); 258 sclp_early_init_core_info(sccb);
327 sclp_hsa_size_detect(sccb); 259 sclp_early_hsa_size_detect(sccb);
328 260
329 /* Turn off SCLP event notifications. Also save remote masks in the 261 /*
262 * Turn off SCLP event notifications. Also save remote masks in the
330 * sccb. These are sufficient to detect sclp console capabilities. 263 * sccb. These are sufficient to detect sclp console capabilities.
331 */ 264 */
332 sclp_set_event_mask(sccb, 0, 0); 265 sclp_early_set_event_mask(sccb, 0, 0);
333 sclp_console_detect(sccb); 266 sclp_early_console_detect(sccb);
334} 267}
diff --git a/drivers/s390/char/sclp_early_core.c b/drivers/s390/char/sclp_early_core.c
new file mode 100644
index 000000000000..5029cc87e80f
--- /dev/null
+++ b/drivers/s390/char/sclp_early_core.c
@@ -0,0 +1,208 @@
1/*
2 * Copyright IBM Corp. 2015
3 * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
4 */
5
6#include <linux/kernel.h>
7#include <asm/processor.h>
8#include <asm/lowcore.h>
9#include <asm/ebcdic.h>
10#include <asm/irq.h>
11#include "sclp.h"
12#include "sclp_rw.h"
13
14char sclp_early_sccb[PAGE_SIZE] __aligned(PAGE_SIZE) __section(data);
15int sclp_init_state __section(data) = sclp_init_state_uninitialized;
16
17void sclp_early_wait_irq(void)
18{
19 unsigned long psw_mask, addr;
20 psw_t psw_ext_save, psw_wait;
21 union ctlreg0 cr0, cr0_new;
22
23 __ctl_store(cr0.val, 0, 0);
24 cr0_new.val = cr0.val & ~CR0_IRQ_SUBCLASS_MASK;
25 cr0_new.lap = 0;
26 cr0_new.sssm = 1;
27 __ctl_load(cr0_new.val, 0, 0);
28
29 psw_ext_save = S390_lowcore.external_new_psw;
30 psw_mask = __extract_psw();
31 S390_lowcore.external_new_psw.mask = psw_mask;
32 psw_wait.mask = psw_mask | PSW_MASK_EXT | PSW_MASK_WAIT;
33 S390_lowcore.ext_int_code = 0;
34
35 do {
36 asm volatile(
37 " larl %[addr],0f\n"
38 " stg %[addr],%[psw_wait_addr]\n"
39 " stg %[addr],%[psw_ext_addr]\n"
40 " lpswe %[psw_wait]\n"
41 "0:\n"
42 : [addr] "=&d" (addr),
43 [psw_wait_addr] "=Q" (psw_wait.addr),
44 [psw_ext_addr] "=Q" (S390_lowcore.external_new_psw.addr)
45 : [psw_wait] "Q" (psw_wait)
46 : "cc", "memory");
47 } while (S390_lowcore.ext_int_code != EXT_IRQ_SERVICE_SIG);
48
49 S390_lowcore.external_new_psw = psw_ext_save;
50 __ctl_load(cr0.val, 0, 0);
51}
52
53int sclp_early_cmd(sclp_cmdw_t cmd, void *sccb)
54{
55 unsigned long flags;
56 int rc;
57
58 raw_local_irq_save(flags);
59 rc = sclp_service_call(cmd, sccb);
60 if (rc)
61 goto out;
62 sclp_early_wait_irq();
63out:
64 raw_local_irq_restore(flags);
65 return rc;
66}
67
68struct write_sccb {
69 struct sccb_header header;
70 struct msg_buf msg;
71} __packed;
72
73/* Output multi-line text using SCLP Message interface. */
74static void sclp_early_print_lm(const char *str, unsigned int len)
75{
76 unsigned char *ptr, *end, ch;
77 unsigned int count, offset;
78 struct write_sccb *sccb;
79 struct msg_buf *msg;
80 struct mdb *mdb;
81 struct mto *mto;
82 struct go *go;
83
84 sccb = (struct write_sccb *) &sclp_early_sccb;
85 end = (unsigned char *) sccb + sizeof(sclp_early_sccb) - 1;
86 memset(sccb, 0, sizeof(*sccb));
87 ptr = (unsigned char *) &sccb->msg.mdb.mto;
88 offset = 0;
89 do {
90 for (count = sizeof(*mto); offset < len; count++) {
91 ch = str[offset++];
92 if ((ch == 0x0a) || (ptr + count > end))
93 break;
94 ptr[count] = _ascebc[ch];
95 }
96 mto = (struct mto *) ptr;
97 memset(mto, 0, sizeof(*mto));
98 mto->length = count;
99 mto->type = 4;
100 mto->line_type_flags = LNTPFLGS_ENDTEXT;
101 ptr += count;
102 } while ((offset < len) && (ptr + sizeof(*mto) <= end));
103 len = ptr - (unsigned char *) sccb;
104 sccb->header.length = len - offsetof(struct write_sccb, header);
105 msg = &sccb->msg;
106 msg->header.type = EVTYP_MSG;
107 msg->header.length = len - offsetof(struct write_sccb, msg.header);
108 mdb = &msg->mdb;
109 mdb->header.type = 1;
110 mdb->header.tag = 0xD4C4C240;
111 mdb->header.revision_code = 1;
112 mdb->header.length = len - offsetof(struct write_sccb, msg.mdb.header);
113 go = &mdb->go;
114 go->length = sizeof(*go);
115 go->type = 1;
116 sclp_early_cmd(SCLP_CMDW_WRITE_EVENT_DATA, sccb);
117}
118
119struct vt220_sccb {
120 struct sccb_header header;
121 struct {
122 struct evbuf_header header;
123 char data[];
124 } msg;
125} __packed;
126
127/* Output multi-line text using SCLP VT220 interface. */
128static void sclp_early_print_vt220(const char *str, unsigned int len)
129{
130 struct vt220_sccb *sccb;
131
132 sccb = (struct vt220_sccb *) &sclp_early_sccb;
133 if (sizeof(*sccb) + len >= sizeof(sclp_early_sccb))
134 len = sizeof(sclp_early_sccb) - sizeof(*sccb);
135 memset(sccb, 0, sizeof(*sccb));
136 memcpy(&sccb->msg.data, str, len);
137 sccb->header.length = sizeof(*sccb) + len;
138 sccb->msg.header.length = sizeof(sccb->msg) + len;
139 sccb->msg.header.type = EVTYP_VT220MSG;
140 sclp_early_cmd(SCLP_CMDW_WRITE_EVENT_DATA, sccb);
141}
142
143int sclp_early_set_event_mask(struct init_sccb *sccb,
144 unsigned long receive_mask,
145 unsigned long send_mask)
146{
147 memset(sccb, 0, sizeof(*sccb));
148 sccb->header.length = sizeof(*sccb);
149 sccb->mask_length = sizeof(sccb_mask_t);
150 sccb->receive_mask = receive_mask;
151 sccb->send_mask = send_mask;
152 if (sclp_early_cmd(SCLP_CMDW_WRITE_EVENT_MASK, sccb))
153 return -EIO;
154 if (sccb->header.response_code != 0x20)
155 return -EIO;
156 return 0;
157}
158
159unsigned int sclp_early_con_check_linemode(struct init_sccb *sccb)
160{
161 if (!(sccb->sclp_send_mask & EVTYP_OPCMD_MASK))
162 return 0;
163 if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
164 return 0;
165 return 1;
166}
167
168static int sclp_early_setup(int disable, int *have_linemode, int *have_vt220)
169{
170 unsigned long receive_mask, send_mask;
171 struct init_sccb *sccb;
172 int rc;
173
174 *have_linemode = *have_vt220 = 0;
175 sccb = (struct init_sccb *) &sclp_early_sccb;
176 receive_mask = disable ? 0 : EVTYP_OPCMD_MASK;
177 send_mask = disable ? 0 : EVTYP_VT220MSG_MASK | EVTYP_MSG_MASK;
178 rc = sclp_early_set_event_mask(sccb, receive_mask, send_mask);
179 if (rc)
180 return rc;
181 *have_linemode = sclp_early_con_check_linemode(sccb);
182 *have_vt220 = sccb->send_mask & EVTYP_VT220MSG_MASK;
183 return rc;
184}
185
186/*
187 * Output one or more lines of text on the SCLP console (VT220 and /
188 * or line-mode).
189 */
190void __sclp_early_printk(const char *str, unsigned int len)
191{
192 int have_linemode, have_vt220;
193
194 if (sclp_init_state != sclp_init_state_uninitialized)
195 return;
196 if (sclp_early_setup(0, &have_linemode, &have_vt220) != 0)
197 return;
198 if (have_linemode)
199 sclp_early_print_lm(str, len);
200 if (have_vt220)
201 sclp_early_print_vt220(str, len);
202 sclp_early_setup(1, &have_linemode, &have_vt220);
203}
204
205void sclp_early_printk(const char *str)
206{
207 __sclp_early_printk(str, strlen(str));
208}
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index d3b51edb056e..aaed778f67c4 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -15,7 +15,6 @@
15 15
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/miscdevice.h>
19#include <linux/debugfs.h> 18#include <linux/debugfs.h>
20#include <linux/memblock.h> 19#include <linux/memblock.h>
21 20
@@ -273,7 +272,7 @@ static int __init zcore_reipl_init(void)
273 rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE); 272 rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
274 else 273 else
275 rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE); 274 rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
276 if (rc || csum_partial(ipl_block, ipl_block->hdr.len, 0) != 275 if (rc || (__force u32)csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
277 ipib_info.checksum) { 276 ipib_info.checksum) {
278 TRACE("Checksum does not match\n"); 277 TRACE("Checksum does not match\n");
279 free_page((unsigned long) ipl_block); 278 free_page((unsigned long) ipl_block);
diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c
index 876c7e6e3a99..7e0d4f724dda 100644
--- a/drivers/s390/cio/chp.c
+++ b/drivers/s390/cio/chp.c
@@ -444,6 +444,7 @@ int chp_update_desc(struct channel_path *chp)
444 */ 444 */
445int chp_new(struct chp_id chpid) 445int chp_new(struct chp_id chpid)
446{ 446{
447 struct channel_subsystem *css = css_by_id(chpid.cssid);
447 struct channel_path *chp; 448 struct channel_path *chp;
448 int ret; 449 int ret;
449 450
@@ -456,7 +457,7 @@ int chp_new(struct chp_id chpid)
456 /* fill in status, etc. */ 457 /* fill in status, etc. */
457 chp->chpid = chpid; 458 chp->chpid = chpid;
458 chp->state = 1; 459 chp->state = 1;
459 chp->dev.parent = &channel_subsystems[chpid.cssid]->device; 460 chp->dev.parent = &css->device;
460 chp->dev.groups = chp_attr_groups; 461 chp->dev.groups = chp_attr_groups;
461 chp->dev.release = chp_release; 462 chp->dev.release = chp_release;
462 mutex_init(&chp->lock); 463 mutex_init(&chp->lock);
@@ -479,17 +480,17 @@ int chp_new(struct chp_id chpid)
479 put_device(&chp->dev); 480 put_device(&chp->dev);
480 goto out; 481 goto out;
481 } 482 }
482 mutex_lock(&channel_subsystems[chpid.cssid]->mutex); 483 mutex_lock(&css->mutex);
483 if (channel_subsystems[chpid.cssid]->cm_enabled) { 484 if (css->cm_enabled) {
484 ret = chp_add_cmg_attr(chp); 485 ret = chp_add_cmg_attr(chp);
485 if (ret) { 486 if (ret) {
486 device_unregister(&chp->dev); 487 device_unregister(&chp->dev);
487 mutex_unlock(&channel_subsystems[chpid.cssid]->mutex); 488 mutex_unlock(&css->mutex);
488 goto out; 489 goto out;
489 } 490 }
490 } 491 }
491 channel_subsystems[chpid.cssid]->chps[chpid.id] = chp; 492 css->chps[chpid.id] = chp;
492 mutex_unlock(&channel_subsystems[chpid.cssid]->mutex); 493 mutex_unlock(&css->mutex);
493 goto out; 494 goto out;
494out_free: 495out_free:
495 kfree(chp); 496 kfree(chp);
diff --git a/drivers/s390/cio/chp.h b/drivers/s390/cio/chp.h
index bb5a68226cda..0d8437b7ea72 100644
--- a/drivers/s390/cio/chp.h
+++ b/drivers/s390/cio/chp.h
@@ -54,7 +54,7 @@ struct channel_path {
54/* Return channel_path struct for given chpid. */ 54/* Return channel_path struct for given chpid. */
55static inline struct channel_path *chpid_to_chp(struct chp_id chpid) 55static inline struct channel_path *chpid_to_chp(struct chp_id chpid)
56{ 56{
57 return channel_subsystems[chpid.cssid]->chps[chpid.id]; 57 return css_by_id(chpid.cssid)->chps[chpid.id];
58} 58}
59 59
60int chp_get_status(struct chp_id chpid); 60int chp_get_status(struct chp_id chpid);
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 11674698b36d..7b0b295b2313 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -1131,6 +1131,52 @@ int chsc_enable_facility(int operation_code)
1131 return ret; 1131 return ret;
1132} 1132}
1133 1133
1134int __init chsc_get_cssid(int idx)
1135{
1136 struct {
1137 struct chsc_header request;
1138 u8 atype;
1139 u32 : 24;
1140 u32 reserved1[6];
1141 struct chsc_header response;
1142 u32 reserved2[3];
1143 struct {
1144 u8 cssid;
1145 u32 : 24;
1146 } list[0];
1147 } __packed *sdcal_area;
1148 int ret;
1149
1150 spin_lock_irq(&chsc_page_lock);
1151 memset(chsc_page, 0, PAGE_SIZE);
1152 sdcal_area = chsc_page;
1153 sdcal_area->request.length = 0x0020;
1154 sdcal_area->request.code = 0x0034;
1155 sdcal_area->atype = 4;
1156
1157 ret = chsc(sdcal_area);
1158 if (ret) {
1159 ret = (ret == 3) ? -ENODEV : -EBUSY;
1160 goto exit;
1161 }
1162
1163 ret = chsc_error_from_response(sdcal_area->response.code);
1164 if (ret) {
1165 CIO_CRW_EVENT(2, "chsc: sdcal failed (rc=%04x)\n",
1166 sdcal_area->response.code);
1167 goto exit;
1168 }
1169
1170 if ((addr_t) &sdcal_area->list[idx] <
1171 (addr_t) &sdcal_area->response + sdcal_area->response.length)
1172 ret = sdcal_area->list[idx].cssid;
1173 else
1174 ret = -ENODEV;
1175exit:
1176 spin_unlock_irq(&chsc_page_lock);
1177 return ret;
1178}
1179
1134struct css_general_char css_general_characteristics; 1180struct css_general_char css_general_characteristics;
1135struct css_chsc_char css_chsc_characteristics; 1181struct css_chsc_char css_chsc_characteristics;
1136 1182
@@ -1216,7 +1262,7 @@ int chsc_sstpi(void *page, void *result, size_t size)
1216 struct chsc_header request; 1262 struct chsc_header request;
1217 unsigned int rsvd0[3]; 1263 unsigned int rsvd0[3];
1218 struct chsc_header response; 1264 struct chsc_header response;
1219 char data[size]; 1265 char data[];
1220 } __attribute__ ((packed)) *rr; 1266 } __attribute__ ((packed)) *rr;
1221 int rc; 1267 int rc;
1222 1268
diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h
index 67c87b6e63ec..321a3f765810 100644
--- a/drivers/s390/cio/chsc.h
+++ b/drivers/s390/cio/chsc.h
@@ -242,6 +242,8 @@ int chsc_pnso_brinfo(struct subchannel_id schid,
242 struct chsc_brinfo_resume_token resume_token, 242 struct chsc_brinfo_resume_token resume_token,
243 int cnc); 243 int cnc);
244 244
245int __init chsc_get_cssid(int idx);
246
245#ifdef CONFIG_SCM_BUS 247#ifdef CONFIG_SCM_BUS
246int scm_update_information(void); 248int scm_update_information(void);
247int scm_process_availability_information(void); 249int scm_process_availability_information(void);
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 6b6386e9a500..220491d27ef4 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -1085,15 +1085,9 @@ static ssize_t cmb_show_avg_utilization(struct device *dev,
1085 data.function_pending_time + 1085 data.function_pending_time +
1086 data.device_disconnect_time; 1086 data.device_disconnect_time;
1087 1087
1088 /* shift to avoid long long division */
1089 while (-1ul < (data.elapsed_time | utilization)) {
1090 utilization >>= 8;
1091 data.elapsed_time >>= 8;
1092 }
1093
1094 /* calculate value in 0.1 percent units */ 1088 /* calculate value in 0.1 percent units */
1095 t = (unsigned long) data.elapsed_time / 1000; 1089 t = data.elapsed_time / 1000;
1096 u = (unsigned long) utilization / t; 1090 u = utilization / t;
1097 1091
1098 return sprintf(buf, "%02ld.%01ld%%\n", u/ 10, u - (u/ 10) * 10); 1092 return sprintf(buf, "%02ld.%01ld%%\n", u/ 10, u - (u/ 10) * 10);
1099} 1093}
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index bc099b61394d..e2aa944eb566 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -36,7 +36,8 @@
36int css_init_done = 0; 36int css_init_done = 0;
37int max_ssid; 37int max_ssid;
38 38
39struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1]; 39#define MAX_CSS_IDX 0
40struct channel_subsystem *channel_subsystems[MAX_CSS_IDX + 1];
40static struct bus_type css_bus_type; 41static struct bus_type css_bus_type;
41 42
42int 43int
@@ -702,7 +703,8 @@ css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
702 703
703 if (css_general_characteristics.mcss) { 704 if (css_general_characteristics.mcss) {
704 css->global_pgid.pgid_high.ext_cssid.version = 0x80; 705 css->global_pgid.pgid_high.ext_cssid.version = 0x80;
705 css->global_pgid.pgid_high.ext_cssid.cssid = css->cssid; 706 css->global_pgid.pgid_high.ext_cssid.cssid =
707 (css->cssid < 0) ? 0 : css->cssid;
706 } else { 708 } else {
707 css->global_pgid.pgid_high.cpu_addr = stap(); 709 css->global_pgid.pgid_high.cpu_addr = stap();
708 } 710 }
@@ -712,43 +714,44 @@ css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
712 css->global_pgid.tod_high = tod_high; 714 css->global_pgid.tod_high = tod_high;
713} 715}
714 716
715static void 717static void channel_subsystem_release(struct device *dev)
716channel_subsystem_release(struct device *dev)
717{ 718{
718 struct channel_subsystem *css; 719 struct channel_subsystem *css = to_css(dev);
719 720
720 css = to_css(dev);
721 mutex_destroy(&css->mutex); 721 mutex_destroy(&css->mutex);
722 if (css->pseudo_subchannel) {
723 /* Implies that it has been generated but never registered. */
724 css_subchannel_release(&css->pseudo_subchannel->dev);
725 css->pseudo_subchannel = NULL;
726 }
727 kfree(css); 722 kfree(css);
728} 723}
729 724
730static ssize_t 725static ssize_t real_cssid_show(struct device *dev, struct device_attribute *a,
731css_cm_enable_show(struct device *dev, struct device_attribute *attr, 726 char *buf)
732 char *buf) 727{
728 struct channel_subsystem *css = to_css(dev);
729
730 if (css->cssid < 0)
731 return -EINVAL;
732
733 return sprintf(buf, "%x\n", css->cssid);
734}
735static DEVICE_ATTR_RO(real_cssid);
736
737static ssize_t cm_enable_show(struct device *dev, struct device_attribute *a,
738 char *buf)
733{ 739{
734 struct channel_subsystem *css = to_css(dev); 740 struct channel_subsystem *css = to_css(dev);
735 int ret; 741 int ret;
736 742
737 if (!css)
738 return 0;
739 mutex_lock(&css->mutex); 743 mutex_lock(&css->mutex);
740 ret = sprintf(buf, "%x\n", css->cm_enabled); 744 ret = sprintf(buf, "%x\n", css->cm_enabled);
741 mutex_unlock(&css->mutex); 745 mutex_unlock(&css->mutex);
742 return ret; 746 return ret;
743} 747}
744 748
745static ssize_t 749static ssize_t cm_enable_store(struct device *dev, struct device_attribute *a,
746css_cm_enable_store(struct device *dev, struct device_attribute *attr, 750 const char *buf, size_t count)
747 const char *buf, size_t count)
748{ 751{
749 struct channel_subsystem *css = to_css(dev); 752 struct channel_subsystem *css = to_css(dev);
750 int ret;
751 unsigned long val; 753 unsigned long val;
754 int ret;
752 755
753 ret = kstrtoul(buf, 16, &val); 756 ret = kstrtoul(buf, 16, &val);
754 if (ret) 757 if (ret)
@@ -767,51 +770,104 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
767 mutex_unlock(&css->mutex); 770 mutex_unlock(&css->mutex);
768 return ret < 0 ? ret : count; 771 return ret < 0 ? ret : count;
769} 772}
773static DEVICE_ATTR_RW(cm_enable);
774
775static umode_t cm_enable_mode(struct kobject *kobj, struct attribute *attr,
776 int index)
777{
778 return css_chsc_characteristics.secm ? attr->mode : 0;
779}
780
781static struct attribute *cssdev_attrs[] = {
782 &dev_attr_real_cssid.attr,
783 NULL,
784};
785
786static struct attribute_group cssdev_attr_group = {
787 .attrs = cssdev_attrs,
788};
789
790static struct attribute *cssdev_cm_attrs[] = {
791 &dev_attr_cm_enable.attr,
792 NULL,
793};
794
795static struct attribute_group cssdev_cm_attr_group = {
796 .attrs = cssdev_cm_attrs,
797 .is_visible = cm_enable_mode,
798};
770 799
771static DEVICE_ATTR(cm_enable, 0644, css_cm_enable_show, css_cm_enable_store); 800static const struct attribute_group *cssdev_attr_groups[] = {
801 &cssdev_attr_group,
802 &cssdev_cm_attr_group,
803 NULL,
804};
772 805
773static int __init setup_css(int nr) 806static int __init setup_css(int nr)
774{ 807{
775 u32 tod_high;
776 int ret;
777 struct channel_subsystem *css; 808 struct channel_subsystem *css;
809 int ret;
778 810
779 css = channel_subsystems[nr]; 811 css = kzalloc(sizeof(*css), GFP_KERNEL);
780 memset(css, 0, sizeof(struct channel_subsystem)); 812 if (!css)
781 css->pseudo_subchannel =
782 kzalloc(sizeof(*css->pseudo_subchannel), GFP_KERNEL);
783 if (!css->pseudo_subchannel)
784 return -ENOMEM; 813 return -ENOMEM;
814
815 channel_subsystems[nr] = css;
816 dev_set_name(&css->device, "css%x", nr);
817 css->device.groups = cssdev_attr_groups;
818 css->device.release = channel_subsystem_release;
819
820 mutex_init(&css->mutex);
821 css->cssid = chsc_get_cssid(nr);
822 css_generate_pgid(css, (u32) (get_tod_clock() >> 32));
823
824 ret = device_register(&css->device);
825 if (ret) {
826 put_device(&css->device);
827 goto out_err;
828 }
829
830 css->pseudo_subchannel = kzalloc(sizeof(*css->pseudo_subchannel),
831 GFP_KERNEL);
832 if (!css->pseudo_subchannel) {
833 device_unregister(&css->device);
834 ret = -ENOMEM;
835 goto out_err;
836 }
837
785 css->pseudo_subchannel->dev.parent = &css->device; 838 css->pseudo_subchannel->dev.parent = &css->device;
786 css->pseudo_subchannel->dev.release = css_subchannel_release; 839 css->pseudo_subchannel->dev.release = css_subchannel_release;
787 dev_set_name(&css->pseudo_subchannel->dev, "defunct");
788 mutex_init(&css->pseudo_subchannel->reg_mutex); 840 mutex_init(&css->pseudo_subchannel->reg_mutex);
789 ret = css_sch_create_locks(css->pseudo_subchannel); 841 ret = css_sch_create_locks(css->pseudo_subchannel);
790 if (ret) { 842 if (ret) {
791 kfree(css->pseudo_subchannel); 843 kfree(css->pseudo_subchannel);
792 return ret; 844 device_unregister(&css->device);
845 goto out_err;
793 } 846 }
794 mutex_init(&css->mutex); 847
795 css->valid = 1; 848 dev_set_name(&css->pseudo_subchannel->dev, "defunct");
796 css->cssid = nr; 849 ret = device_register(&css->pseudo_subchannel->dev);
797 dev_set_name(&css->device, "css%x", nr); 850 if (ret) {
798 css->device.release = channel_subsystem_release; 851 put_device(&css->pseudo_subchannel->dev);
799 tod_high = (u32) (get_tod_clock() >> 32); 852 device_unregister(&css->device);
800 css_generate_pgid(css, tod_high); 853 goto out_err;
801 return 0; 854 }
855
856 return ret;
857out_err:
858 channel_subsystems[nr] = NULL;
859 return ret;
802} 860}
803 861
804static int css_reboot_event(struct notifier_block *this, 862static int css_reboot_event(struct notifier_block *this,
805 unsigned long event, 863 unsigned long event,
806 void *ptr) 864 void *ptr)
807{ 865{
808 int ret, i; 866 struct channel_subsystem *css;
867 int ret;
809 868
810 ret = NOTIFY_DONE; 869 ret = NOTIFY_DONE;
811 for (i = 0; i <= __MAX_CSSID; i++) { 870 for_each_css(css) {
812 struct channel_subsystem *css;
813
814 css = channel_subsystems[i];
815 mutex_lock(&css->mutex); 871 mutex_lock(&css->mutex);
816 if (css->cm_enabled) 872 if (css->cm_enabled)
817 if (chsc_secm(css, 0)) 873 if (chsc_secm(css, 0))
@@ -835,16 +891,14 @@ static struct notifier_block css_reboot_notifier = {
835static int css_power_event(struct notifier_block *this, unsigned long event, 891static int css_power_event(struct notifier_block *this, unsigned long event,
836 void *ptr) 892 void *ptr)
837{ 893{
838 int ret, i; 894 struct channel_subsystem *css;
895 int ret;
839 896
840 switch (event) { 897 switch (event) {
841 case PM_HIBERNATION_PREPARE: 898 case PM_HIBERNATION_PREPARE:
842 case PM_SUSPEND_PREPARE: 899 case PM_SUSPEND_PREPARE:
843 ret = NOTIFY_DONE; 900 ret = NOTIFY_DONE;
844 for (i = 0; i <= __MAX_CSSID; i++) { 901 for_each_css(css) {
845 struct channel_subsystem *css;
846
847 css = channel_subsystems[i];
848 mutex_lock(&css->mutex); 902 mutex_lock(&css->mutex);
849 if (!css->cm_enabled) { 903 if (!css->cm_enabled) {
850 mutex_unlock(&css->mutex); 904 mutex_unlock(&css->mutex);
@@ -858,10 +912,7 @@ static int css_power_event(struct notifier_block *this, unsigned long event,
858 case PM_POST_HIBERNATION: 912 case PM_POST_HIBERNATION:
859 case PM_POST_SUSPEND: 913 case PM_POST_SUSPEND:
860 ret = NOTIFY_DONE; 914 ret = NOTIFY_DONE;
861 for (i = 0; i <= __MAX_CSSID; i++) { 915 for_each_css(css) {
862 struct channel_subsystem *css;
863
864 css = channel_subsystems[i];
865 mutex_lock(&css->mutex); 916 mutex_lock(&css->mutex);
866 if (!css->cm_enabled) { 917 if (!css->cm_enabled) {
867 mutex_unlock(&css->mutex); 918 mutex_unlock(&css->mutex);
@@ -916,36 +967,10 @@ static int __init css_bus_init(void)
916 goto out; 967 goto out;
917 968
918 /* Setup css structure. */ 969 /* Setup css structure. */
919 for (i = 0; i <= __MAX_CSSID; i++) { 970 for (i = 0; i <= MAX_CSS_IDX; i++) {
920 struct channel_subsystem *css;
921
922 css = kmalloc(sizeof(struct channel_subsystem), GFP_KERNEL);
923 if (!css) {
924 ret = -ENOMEM;
925 goto out_unregister;
926 }
927 channel_subsystems[i] = css;
928 ret = setup_css(i); 971 ret = setup_css(i);
929 if (ret) { 972 if (ret)
930 kfree(channel_subsystems[i]);
931 goto out_unregister;
932 }
933 ret = device_register(&css->device);
934 if (ret) {
935 put_device(&css->device);
936 goto out_unregister; 973 goto out_unregister;
937 }
938 if (css_chsc_characteristics.secm) {
939 ret = device_create_file(&css->device,
940 &dev_attr_cm_enable);
941 if (ret)
942 goto out_device;
943 }
944 ret = device_register(&css->pseudo_subchannel->dev);
945 if (ret) {
946 put_device(&css->pseudo_subchannel->dev);
947 goto out_file;
948 }
949 } 974 }
950 ret = register_reboot_notifier(&css_reboot_notifier); 975 ret = register_reboot_notifier(&css_reboot_notifier);
951 if (ret) 976 if (ret)
@@ -961,23 +986,10 @@ static int __init css_bus_init(void)
961 isc_register(IO_SCH_ISC); 986 isc_register(IO_SCH_ISC);
962 987
963 return 0; 988 return 0;
964out_file:
965 if (css_chsc_characteristics.secm)
966 device_remove_file(&channel_subsystems[i]->device,
967 &dev_attr_cm_enable);
968out_device:
969 device_unregister(&channel_subsystems[i]->device);
970out_unregister: 989out_unregister:
971 while (i > 0) { 990 while (i-- > 0) {
972 struct channel_subsystem *css; 991 struct channel_subsystem *css = channel_subsystems[i];
973
974 i--;
975 css = channel_subsystems[i];
976 device_unregister(&css->pseudo_subchannel->dev); 992 device_unregister(&css->pseudo_subchannel->dev);
977 css->pseudo_subchannel = NULL;
978 if (css_chsc_characteristics.secm)
979 device_remove_file(&css->device,
980 &dev_attr_cm_enable);
981 device_unregister(&css->device); 993 device_unregister(&css->device);
982 } 994 }
983 bus_unregister(&css_bus_type); 995 bus_unregister(&css_bus_type);
@@ -993,14 +1005,9 @@ out:
993static void __init css_bus_cleanup(void) 1005static void __init css_bus_cleanup(void)
994{ 1006{
995 struct channel_subsystem *css; 1007 struct channel_subsystem *css;
996 int i;
997 1008
998 for (i = 0; i <= __MAX_CSSID; i++) { 1009 for_each_css(css) {
999 css = channel_subsystems[i];
1000 device_unregister(&css->pseudo_subchannel->dev); 1010 device_unregister(&css->pseudo_subchannel->dev);
1001 css->pseudo_subchannel = NULL;
1002 if (css_chsc_characteristics.secm)
1003 device_remove_file(&css->device, &dev_attr_cm_enable);
1004 device_unregister(&css->device); 1011 device_unregister(&css->device);
1005 } 1012 }
1006 bus_unregister(&css_bus_type); 1013 bus_unregister(&css_bus_type);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 2c9107e20251..c9f3fb39ebeb 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -113,8 +113,7 @@ extern int for_each_subchannel(int(*fn)(struct subchannel_id, void *), void *);
113void css_update_ssd_info(struct subchannel *sch); 113void css_update_ssd_info(struct subchannel *sch);
114 114
115struct channel_subsystem { 115struct channel_subsystem {
116 u8 cssid; 116 int cssid;
117 int valid;
118 struct channel_path *chps[__MAX_CHPID + 1]; 117 struct channel_path *chps[__MAX_CHPID + 1];
119 struct device device; 118 struct device device;
120 struct pgid global_pgid; 119 struct pgid global_pgid;
@@ -130,6 +129,16 @@ struct channel_subsystem {
130 129
131extern struct channel_subsystem *channel_subsystems[]; 130extern struct channel_subsystem *channel_subsystems[];
132 131
132/* Dummy helper which needs to change once we support more than one css. */
133static inline struct channel_subsystem *css_by_id(u8 cssid)
134{
135 return channel_subsystems[0];
136}
137
138/* Dummy iterator which needs to change once we support more than one css. */
139#define for_each_css(css) \
140 for ((css) = channel_subsystems[0]; (css); (css) = NULL)
141
133/* Helper functions to build lists for the slow path. */ 142/* Helper functions to build lists for the slow path. */
134void css_schedule_eval(struct subchannel_id schid); 143void css_schedule_eval(struct subchannel_id schid);
135void css_schedule_eval_all(void); 144void css_schedule_eval_all(void);
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 71bf9bded485..a4ad39ba3873 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -457,7 +457,7 @@ static inline void inbound_primed(struct qdio_q *q, int count)
457{ 457{
458 int new; 458 int new;
459 459
460 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim: %02x", count); 460 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim:%1d %02x", q->nr, count);
461 461
462 /* for QEBSM the ACK was already set by EQBS */ 462 /* for QEBSM the ACK was already set by EQBS */
463 if (is_qebsm(q)) { 463 if (is_qebsm(q)) {
@@ -544,7 +544,8 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
544 case SLSB_P_INPUT_ACK: 544 case SLSB_P_INPUT_ACK:
545 if (q->irq_ptr->perf_stat_enabled) 545 if (q->irq_ptr->perf_stat_enabled)
546 q->q_stats.nr_sbal_nop++; 546 q->q_stats.nr_sbal_nop++;
547 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop"); 547 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop:%1d %#02x",
548 q->nr, q->first_to_check);
548 break; 549 break;
549 default: 550 default:
550 WARN_ON_ONCE(1); 551 WARN_ON_ONCE(1);
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 5d06253c2a7a..8ad98a902a91 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -147,11 +147,11 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
147 struct qdio_q *q; 147 struct qdio_q *q;
148 int i; 148 int i;
149 149
150 for_each_input_queue(irq, q, i) { 150 if (!references_shared_dsci(irq) &&
151 if (!references_shared_dsci(irq) && 151 has_multiple_inq_on_dsci(irq))
152 has_multiple_inq_on_dsci(irq)) 152 xchg(irq->dsci, 0);
153 xchg(q->irq_ptr->dsci, 0);
154 153
154 for_each_input_queue(irq, q, i) {
155 if (q->u.in.queue_start_poll) { 155 if (q->u.in.queue_start_poll) {
156 /* skip if polling is enabled or already in work */ 156 /* skip if polling is enabled or already in work */
157 if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED, 157 if (test_and_set_bit(QDIO_QUEUE_IRQS_DISABLED,
@@ -161,11 +161,11 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
161 } 161 }
162 162
163 /* avoid dsci clear here, done after processing */ 163 /* avoid dsci clear here, done after processing */
164 q->u.in.queue_start_poll(q->irq_ptr->cdev, q->nr, 164 q->u.in.queue_start_poll(irq->cdev, q->nr,
165 q->irq_ptr->int_parm); 165 irq->int_parm);
166 } else { 166 } else {
167 if (!shared_ind(q->irq_ptr)) 167 if (!shared_ind(irq))
168 xchg(q->irq_ptr->dsci, 0); 168 xchg(irq->dsci, 0);
169 169
170 /* 170 /*
171 * Call inbound processing but not directly 171 * Call inbound processing but not directly
@@ -178,8 +178,7 @@ static inline void tiqdio_call_inq_handlers(struct qdio_irq *irq)
178 178
179/** 179/**
180 * tiqdio_thinint_handler - thin interrupt handler for qdio 180 * tiqdio_thinint_handler - thin interrupt handler for qdio
181 * @alsi: pointer to adapter local summary indicator 181 * @airq: pointer to adapter interrupt descriptor
182 * @data: NULL
183 */ 182 */
184static void tiqdio_thinint_handler(struct airq_struct *airq) 183static void tiqdio_thinint_handler(struct airq_struct *airq)
185{ 184{
diff --git a/drivers/s390/crypto/ap_asm.h b/drivers/s390/crypto/ap_asm.h
index 7a630047c372..287b4ad0999e 100644
--- a/drivers/s390/crypto/ap_asm.h
+++ b/drivers/s390/crypto/ap_asm.h
@@ -129,7 +129,6 @@ static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
129 unsigned long long psmid, 129 unsigned long long psmid,
130 void *msg, size_t length) 130 void *msg, size_t length)
131{ 131{
132 struct msgblock { char _[length]; };
133 register unsigned long reg0 asm ("0") = qid | 0x40000000UL; 132 register unsigned long reg0 asm ("0") = qid | 0x40000000UL;
134 register struct ap_queue_status reg1 asm ("1"); 133 register struct ap_queue_status reg1 asm ("1");
135 register unsigned long reg2 asm ("2") = (unsigned long) msg; 134 register unsigned long reg2 asm ("2") = (unsigned long) msg;
@@ -141,8 +140,8 @@ static inline struct ap_queue_status ap_nqap(ap_qid_t qid,
141 "0: .long 0xb2ad0042\n" /* NQAP */ 140 "0: .long 0xb2ad0042\n" /* NQAP */
142 " brc 2,0b" 141 " brc 2,0b"
143 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3) 142 : "+d" (reg0), "=d" (reg1), "+d" (reg2), "+d" (reg3)
144 : "d" (reg4), "d" (reg5), "m" (*(struct msgblock *) msg) 143 : "d" (reg4), "d" (reg5)
145 : "cc"); 144 : "cc", "memory");
146 return reg1; 145 return reg1;
147} 146}
148 147
@@ -168,7 +167,6 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
168 unsigned long long *psmid, 167 unsigned long long *psmid,
169 void *msg, size_t length) 168 void *msg, size_t length)
170{ 169{
171 struct msgblock { char _[length]; };
172 register unsigned long reg0 asm("0") = qid | 0x80000000UL; 170 register unsigned long reg0 asm("0") = qid | 0x80000000UL;
173 register struct ap_queue_status reg1 asm ("1"); 171 register struct ap_queue_status reg1 asm ("1");
174 register unsigned long reg2 asm("2") = 0UL; 172 register unsigned long reg2 asm("2") = 0UL;
@@ -182,8 +180,8 @@ static inline struct ap_queue_status ap_dqap(ap_qid_t qid,
182 "0: .long 0xb2ae0064\n" /* DQAP */ 180 "0: .long 0xb2ae0064\n" /* DQAP */
183 " brc 6,0b\n" 181 " brc 6,0b\n"
184 : "+d" (reg0), "=d" (reg1), "+d" (reg2), 182 : "+d" (reg0), "=d" (reg1), "+d" (reg2),
185 "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7), 183 "+d" (reg4), "+d" (reg5), "+d" (reg6), "+d" (reg7)
186 "=m" (*(struct msgblock *) msg) : : "cc"); 184 : : "cc", "memory");
187 *psmid = (((unsigned long long) reg6) << 32) + reg7; 185 *psmid = (((unsigned long long) reg6) << 32) + reg7;
188 return reg1; 186 return reg1;
189} 187}
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 5fa699192864..56db76c05775 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -27,7 +27,7 @@
27#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 27#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
28 28
29#include <linux/kernel_stat.h> 29#include <linux/kernel_stat.h>
30#include <linux/module.h> 30#include <linux/moduleparam.h>
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/err.h> 33#include <linux/err.h>
@@ -54,16 +54,7 @@
54#include "ap_debug.h" 54#include "ap_debug.h"
55 55
56/* 56/*
57 * Module description. 57 * Module parameters; note though this file itself isn't modular.
58 */
59MODULE_AUTHOR("IBM Corporation");
60MODULE_DESCRIPTION("Adjunct Processor Bus driver, " \
61 "Copyright IBM Corp. 2006, 2012");
62MODULE_LICENSE("GPL");
63MODULE_ALIAS_CRYPTO("z90crypt");
64
65/*
66 * Module parameter
67 */ 58 */
68int ap_domain_index = -1; /* Adjunct Processor Domain Index */ 59int ap_domain_index = -1; /* Adjunct Processor Domain Index */
69static DEFINE_SPINLOCK(ap_domain_lock); 60static DEFINE_SPINLOCK(ap_domain_lock);
@@ -86,7 +77,6 @@ static bool initialised;
86/* 77/*
87 * AP bus related debug feature things. 78 * AP bus related debug feature things.
88 */ 79 */
89static struct dentry *ap_dbf_root;
90debug_info_t *ap_dbf_info; 80debug_info_t *ap_dbf_info;
91 81
92/* 82/*
@@ -1148,7 +1138,6 @@ static struct reset_call ap_reset_call = {
1148 1138
1149int __init ap_debug_init(void) 1139int __init ap_debug_init(void)
1150{ 1140{
1151 ap_dbf_root = debugfs_create_dir("ap", NULL);
1152 ap_dbf_info = debug_register("ap", 1, 1, 1141 ap_dbf_info = debug_register("ap", 1, 1,
1153 DBF_MAX_SPRINTF_ARGS * sizeof(long)); 1142 DBF_MAX_SPRINTF_ARGS * sizeof(long));
1154 debug_register_view(ap_dbf_info, &debug_sprintf_view); 1143 debug_register_view(ap_dbf_info, &debug_sprintf_view);
@@ -1159,7 +1148,6 @@ int __init ap_debug_init(void)
1159 1148
1160void ap_debug_exit(void) 1149void ap_debug_exit(void)
1161{ 1150{
1162 debugfs_remove(ap_dbf_root);
1163 debug_unregister(ap_dbf_info); 1151 debug_unregister(ap_dbf_info);
1164} 1152}
1165 1153
@@ -1270,43 +1258,4 @@ out_free:
1270 kfree(ap_configuration); 1258 kfree(ap_configuration);
1271 return rc; 1259 return rc;
1272} 1260}
1273 1261device_initcall(ap_module_init);
1274/**
1275 * ap_modules_exit(): The module termination code
1276 *
1277 * Terminates the module.
1278 */
1279void ap_module_exit(void)
1280{
1281 int i;
1282
1283 initialised = false;
1284 ap_reset_domain();
1285 ap_poll_thread_stop();
1286 del_timer_sync(&ap_config_timer);
1287 hrtimer_cancel(&ap_poll_timer);
1288 tasklet_kill(&ap_tasklet);
1289
1290 /* first remove queue devices */
1291 bus_for_each_dev(&ap_bus_type, NULL, NULL,
1292 __ap_queue_devices_unregister);
1293 /* now remove the card devices */
1294 bus_for_each_dev(&ap_bus_type, NULL, NULL,
1295 __ap_card_devices_unregister);
1296
1297 /* remove bus attributes */
1298 for (i = 0; ap_bus_attrs[i]; i++)
1299 bus_remove_file(&ap_bus_type, ap_bus_attrs[i]);
1300 unregister_pm_notifier(&ap_power_notifier);
1301 root_device_unregister(ap_root_device);
1302 bus_unregister(&ap_bus_type);
1303 kfree(ap_configuration);
1304 unregister_reset_call(&ap_reset_call);
1305 if (ap_using_interrupts())
1306 unregister_adapter_interrupt(&ap_airq);
1307
1308 ap_debug_exit();
1309}
1310
1311module_init(ap_module_init);
1312module_exit(ap_module_exit);
diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c
index 0110d44172a3..1cd9128593e4 100644
--- a/drivers/s390/crypto/ap_card.c
+++ b/drivers/s390/crypto/ap_card.c
@@ -137,7 +137,7 @@ static const struct attribute_group *ap_card_dev_attr_groups[] = {
137 NULL 137 NULL
138}; 138};
139 139
140struct device_type ap_card_type = { 140static struct device_type ap_card_type = {
141 .name = "ap_card", 141 .name = "ap_card",
142 .groups = ap_card_dev_attr_groups, 142 .groups = ap_card_dev_attr_groups,
143}; 143};
diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c
index b58a917dc510..7be67fa9f224 100644
--- a/drivers/s390/crypto/ap_queue.c
+++ b/drivers/s390/crypto/ap_queue.c
@@ -564,7 +564,7 @@ static const struct attribute_group *ap_queue_dev_attr_groups[] = {
564 NULL 564 NULL
565}; 565};
566 566
567struct device_type ap_queue_type = { 567static struct device_type ap_queue_type = {
568 .name = "ap_queue", 568 .name = "ap_queue",
569 .groups = ap_queue_dev_attr_groups, 569 .groups = ap_queue_dev_attr_groups,
570}; 570};
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index 51eece9af577..144a17941e6f 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -81,7 +81,6 @@ EXPORT_SYMBOL(zcrypt_rescan_req);
81static LIST_HEAD(zcrypt_ops_list); 81static LIST_HEAD(zcrypt_ops_list);
82 82
83/* Zcrypt related debug feature stuff. */ 83/* Zcrypt related debug feature stuff. */
84static struct dentry *zcrypt_dbf_root;
85debug_info_t *zcrypt_dbf_info; 84debug_info_t *zcrypt_dbf_info;
86 85
87/** 86/**
@@ -201,7 +200,7 @@ static inline bool zcrypt_card_compare(struct zcrypt_card *zc,
201 unsigned weight, unsigned pref_weight) 200 unsigned weight, unsigned pref_weight)
202{ 201{
203 if (!pref_zc) 202 if (!pref_zc)
204 return 0; 203 return false;
205 weight += atomic_read(&zc->load); 204 weight += atomic_read(&zc->load);
206 pref_weight += atomic_read(&pref_zc->load); 205 pref_weight += atomic_read(&pref_zc->load);
207 if (weight == pref_weight) 206 if (weight == pref_weight)
@@ -215,7 +214,7 @@ static inline bool zcrypt_queue_compare(struct zcrypt_queue *zq,
215 unsigned weight, unsigned pref_weight) 214 unsigned weight, unsigned pref_weight)
216{ 215{
217 if (!pref_zq) 216 if (!pref_zq)
218 return 0; 217 return false;
219 weight += atomic_read(&zq->load); 218 weight += atomic_read(&zq->load);
220 pref_weight += atomic_read(&pref_zq->load); 219 pref_weight += atomic_read(&pref_zq->load);
221 if (weight == pref_weight) 220 if (weight == pref_weight)
@@ -668,6 +667,7 @@ static void zcrypt_qdepth_mask(char qdepth[AP_DEVICES])
668 667
669 memset(qdepth, 0, sizeof(char) * AP_DEVICES); 668 memset(qdepth, 0, sizeof(char) * AP_DEVICES);
670 spin_lock(&zcrypt_list_lock); 669 spin_lock(&zcrypt_list_lock);
670 local_bh_disable();
671 for_each_zcrypt_card(zc) { 671 for_each_zcrypt_card(zc) {
672 for_each_zcrypt_queue(zq, zc) { 672 for_each_zcrypt_queue(zq, zc) {
673 if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index) 673 if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
@@ -679,6 +679,7 @@ static void zcrypt_qdepth_mask(char qdepth[AP_DEVICES])
679 spin_unlock(&zq->queue->lock); 679 spin_unlock(&zq->queue->lock);
680 } 680 }
681 } 681 }
682 local_bh_enable();
682 spin_unlock(&zcrypt_list_lock); 683 spin_unlock(&zcrypt_list_lock);
683} 684}
684 685
@@ -689,6 +690,7 @@ static void zcrypt_perdev_reqcnt(int reqcnt[AP_DEVICES])
689 690
690 memset(reqcnt, 0, sizeof(int) * AP_DEVICES); 691 memset(reqcnt, 0, sizeof(int) * AP_DEVICES);
691 spin_lock(&zcrypt_list_lock); 692 spin_lock(&zcrypt_list_lock);
693 local_bh_disable();
692 for_each_zcrypt_card(zc) { 694 for_each_zcrypt_card(zc) {
693 for_each_zcrypt_queue(zq, zc) { 695 for_each_zcrypt_queue(zq, zc) {
694 if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index) 696 if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
@@ -699,6 +701,7 @@ static void zcrypt_perdev_reqcnt(int reqcnt[AP_DEVICES])
699 spin_unlock(&zq->queue->lock); 701 spin_unlock(&zq->queue->lock);
700 } 702 }
701 } 703 }
704 local_bh_enable();
702 spin_unlock(&zcrypt_list_lock); 705 spin_unlock(&zcrypt_list_lock);
703} 706}
704 707
@@ -710,6 +713,7 @@ static int zcrypt_pendingq_count(void)
710 713
711 pendingq_count = 0; 714 pendingq_count = 0;
712 spin_lock(&zcrypt_list_lock); 715 spin_lock(&zcrypt_list_lock);
716 local_bh_disable();
713 for_each_zcrypt_card(zc) { 717 for_each_zcrypt_card(zc) {
714 for_each_zcrypt_queue(zq, zc) { 718 for_each_zcrypt_queue(zq, zc) {
715 if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index) 719 if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
@@ -719,6 +723,7 @@ static int zcrypt_pendingq_count(void)
719 spin_unlock(&zq->queue->lock); 723 spin_unlock(&zq->queue->lock);
720 } 724 }
721 } 725 }
726 local_bh_enable();
722 spin_unlock(&zcrypt_list_lock); 727 spin_unlock(&zcrypt_list_lock);
723 return pendingq_count; 728 return pendingq_count;
724} 729}
@@ -731,6 +736,7 @@ static int zcrypt_requestq_count(void)
731 736
732 requestq_count = 0; 737 requestq_count = 0;
733 spin_lock(&zcrypt_list_lock); 738 spin_lock(&zcrypt_list_lock);
739 local_bh_disable();
734 for_each_zcrypt_card(zc) { 740 for_each_zcrypt_card(zc) {
735 for_each_zcrypt_queue(zq, zc) { 741 for_each_zcrypt_queue(zq, zc) {
736 if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index) 742 if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index)
@@ -740,6 +746,7 @@ static int zcrypt_requestq_count(void)
740 spin_unlock(&zq->queue->lock); 746 spin_unlock(&zq->queue->lock);
741 } 747 }
742 } 748 }
749 local_bh_enable();
743 spin_unlock(&zcrypt_list_lock); 750 spin_unlock(&zcrypt_list_lock);
744 return requestq_count; 751 return requestq_count;
745} 752}
@@ -1419,7 +1426,6 @@ void zcrypt_rng_device_remove(void)
1419 1426
1420int __init zcrypt_debug_init(void) 1427int __init zcrypt_debug_init(void)
1421{ 1428{
1422 zcrypt_dbf_root = debugfs_create_dir("zcrypt", NULL);
1423 zcrypt_dbf_info = debug_register("zcrypt", 1, 1, 1429 zcrypt_dbf_info = debug_register("zcrypt", 1, 1,
1424 DBF_MAX_SPRINTF_ARGS * sizeof(long)); 1430 DBF_MAX_SPRINTF_ARGS * sizeof(long));
1425 debug_register_view(zcrypt_dbf_info, &debug_sprintf_view); 1431 debug_register_view(zcrypt_dbf_info, &debug_sprintf_view);
@@ -1430,7 +1436,6 @@ int __init zcrypt_debug_init(void)
1430 1436
1431void zcrypt_debug_exit(void) 1437void zcrypt_debug_exit(void)
1432{ 1438{
1433 debugfs_remove(zcrypt_dbf_root);
1434 debug_unregister(zcrypt_dbf_info); 1439 debug_unregister(zcrypt_dbf_info);
1435} 1440}
1436 1441
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
index 070c4da95f48..648373cde4a1 100644
--- a/drivers/s390/virtio/virtio_ccw.c
+++ b/drivers/s390/virtio/virtio_ccw.c
@@ -661,7 +661,7 @@ static int virtio_ccw_find_vqs(struct virtio_device *vdev, unsigned nvqs,
661 ret = virtio_ccw_register_adapter_ind(vcdev, vqs, nvqs, ccw); 661 ret = virtio_ccw_register_adapter_ind(vcdev, vqs, nvqs, ccw);
662 if (ret) 662 if (ret)
663 /* no error, just fall back to legacy interrupts */ 663 /* no error, just fall back to legacy interrupts */
664 vcdev->is_thinint = 0; 664 vcdev->is_thinint = false;
665 } 665 }
666 if (!vcdev->is_thinint) { 666 if (!vcdev->is_thinint) {
667 /* Register queue indicators with host. */ 667 /* Register queue indicators with host. */