diff options
Diffstat (limited to 'drivers/s390')
36 files changed, 262 insertions, 329 deletions
diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c index fd1231738ef4..148b1dd24070 100644 --- a/drivers/s390/block/dasd_alias.c +++ b/drivers/s390/block/dasd_alias.c | |||
@@ -218,7 +218,7 @@ int dasd_alias_make_device_known_to_lcu(struct dasd_device *device) | |||
218 | spin_unlock_irqrestore(&aliastree.lock, flags); | 218 | spin_unlock_irqrestore(&aliastree.lock, flags); |
219 | newlcu = _allocate_lcu(uid); | 219 | newlcu = _allocate_lcu(uid); |
220 | if (IS_ERR(newlcu)) | 220 | if (IS_ERR(newlcu)) |
221 | return PTR_ERR(lcu); | 221 | return PTR_ERR(newlcu); |
222 | spin_lock_irqsave(&aliastree.lock, flags); | 222 | spin_lock_irqsave(&aliastree.lock, flags); |
223 | lcu = _find_lcu(server, uid); | 223 | lcu = _find_lcu(server, uid); |
224 | if (!lcu) { | 224 | if (!lcu) { |
diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index f64d0db881b4..6e14863f5c70 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c | |||
@@ -8,7 +8,7 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define KMSG_COMPONENT "dasd-diag" | 11 | #define KMSG_COMPONENT "dasd" |
12 | 12 | ||
13 | #include <linux/stddef.h> | 13 | #include <linux/stddef.h> |
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
@@ -146,16 +146,16 @@ dasd_diag_erp(struct dasd_device *device) | |||
146 | rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); | 146 | rc = mdsk_init_io(device, device->block->bp_block, 0, NULL); |
147 | if (rc == 4) { | 147 | if (rc == 4) { |
148 | if (!(device->features & DASD_FEATURE_READONLY)) { | 148 | if (!(device->features & DASD_FEATURE_READONLY)) { |
149 | dev_warn(&device->cdev->dev, | 149 | pr_warning("%s: The access mode of a DIAG device " |
150 | "The access mode of a DIAG device changed" | 150 | "changed to read-only\n", |
151 | " to read-only"); | 151 | dev_name(&device->cdev->dev)); |
152 | device->features |= DASD_FEATURE_READONLY; | 152 | device->features |= DASD_FEATURE_READONLY; |
153 | } | 153 | } |
154 | rc = 0; | 154 | rc = 0; |
155 | } | 155 | } |
156 | if (rc) | 156 | if (rc) |
157 | dev_warn(&device->cdev->dev, "DIAG ERP failed with " | 157 | pr_warning("%s: DIAG ERP failed with " |
158 | "rc=%d\n", rc); | 158 | "rc=%d\n", dev_name(&device->cdev->dev), rc); |
159 | } | 159 | } |
160 | 160 | ||
161 | /* Start a given request at the device. Return zero on success, non-zero | 161 | /* Start a given request at the device. Return zero on success, non-zero |
@@ -371,8 +371,9 @@ dasd_diag_check_device(struct dasd_device *device) | |||
371 | private->pt_block = 2; | 371 | private->pt_block = 2; |
372 | break; | 372 | break; |
373 | default: | 373 | default: |
374 | dev_warn(&device->cdev->dev, "Device type %d is not supported " | 374 | pr_warning("%s: Device type %d is not supported " |
375 | "in DIAG mode\n", private->rdc_data.vdev_class); | 375 | "in DIAG mode\n", dev_name(&device->cdev->dev), |
376 | private->rdc_data.vdev_class); | ||
376 | rc = -EOPNOTSUPP; | 377 | rc = -EOPNOTSUPP; |
377 | goto out; | 378 | goto out; |
378 | } | 379 | } |
@@ -413,8 +414,8 @@ dasd_diag_check_device(struct dasd_device *device) | |||
413 | private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; | 414 | private->iob.flaga = DASD_DIAG_FLAGA_DEFAULT; |
414 | rc = dia250(&private->iob, RW_BIO); | 415 | rc = dia250(&private->iob, RW_BIO); |
415 | if (rc == 3) { | 416 | if (rc == 3) { |
416 | dev_warn(&device->cdev->dev, | 417 | pr_warning("%s: A 64-bit DIAG call failed\n", |
417 | "A 64-bit DIAG call failed\n"); | 418 | dev_name(&device->cdev->dev)); |
418 | rc = -EOPNOTSUPP; | 419 | rc = -EOPNOTSUPP; |
419 | goto out_label; | 420 | goto out_label; |
420 | } | 421 | } |
@@ -423,8 +424,9 @@ dasd_diag_check_device(struct dasd_device *device) | |||
423 | break; | 424 | break; |
424 | } | 425 | } |
425 | if (bsize > PAGE_SIZE) { | 426 | if (bsize > PAGE_SIZE) { |
426 | dev_warn(&device->cdev->dev, "Accessing the DASD failed because" | 427 | pr_warning("%s: Accessing the DASD failed because of an " |
427 | " of an incorrect format (rc=%d)\n", rc); | 428 | "incorrect format (rc=%d)\n", |
429 | dev_name(&device->cdev->dev), rc); | ||
428 | rc = -EIO; | 430 | rc = -EIO; |
429 | goto out_label; | 431 | goto out_label; |
430 | } | 432 | } |
@@ -442,18 +444,18 @@ dasd_diag_check_device(struct dasd_device *device) | |||
442 | block->s2b_shift++; | 444 | block->s2b_shift++; |
443 | rc = mdsk_init_io(device, block->bp_block, 0, NULL); | 445 | rc = mdsk_init_io(device, block->bp_block, 0, NULL); |
444 | if (rc && (rc != 4)) { | 446 | if (rc && (rc != 4)) { |
445 | dev_warn(&device->cdev->dev, "DIAG initialization " | 447 | pr_warning("%s: DIAG initialization failed with rc=%d\n", |
446 | "failed with rc=%d\n", rc); | 448 | dev_name(&device->cdev->dev), rc); |
447 | rc = -EIO; | 449 | rc = -EIO; |
448 | } else { | 450 | } else { |
449 | if (rc == 4) | 451 | if (rc == 4) |
450 | device->features |= DASD_FEATURE_READONLY; | 452 | device->features |= DASD_FEATURE_READONLY; |
451 | dev_info(&device->cdev->dev, | 453 | pr_info("%s: New DASD with %ld byte/block, total size %ld " |
452 | "New DASD with %ld byte/block, total size %ld KB%s\n", | 454 | "KB%s\n", dev_name(&device->cdev->dev), |
453 | (unsigned long) block->bp_block, | 455 | (unsigned long) block->bp_block, |
454 | (unsigned long) (block->blocks << | 456 | (unsigned long) (block->blocks << |
455 | block->s2b_shift) >> 1, | 457 | block->s2b_shift) >> 1, |
456 | (rc == 4) ? ", read-only device" : ""); | 458 | (rc == 4) ? ", read-only device" : ""); |
457 | rc = 0; | 459 | rc = 0; |
458 | } | 460 | } |
459 | out_label: | 461 | out_label: |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 5f23eca82804..6315fbd8e68b 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #define KMSG_COMPONENT "dasd" | 14 | #define KMSG_COMPONENT "dasd" |
15 | 15 | ||
16 | #include <linux/ctype.h> | 16 | #include <linux/ctype.h> |
17 | #include <linux/string.h> | ||
17 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
18 | #include <linux/vmalloc.h> | 19 | #include <linux/vmalloc.h> |
19 | #include <linux/proc_fs.h> | 20 | #include <linux/proc_fs.h> |
@@ -272,10 +273,10 @@ dasd_statistics_write(struct file *file, const char __user *user_buf, | |||
272 | DBF_EVENT(DBF_DEBUG, "/proc/dasd/statictics: '%s'\n", buffer); | 273 | DBF_EVENT(DBF_DEBUG, "/proc/dasd/statictics: '%s'\n", buffer); |
273 | 274 | ||
274 | /* check for valid verbs */ | 275 | /* check for valid verbs */ |
275 | for (str = buffer; isspace(*str); str++); | 276 | str = skip_spaces(buffer); |
276 | if (strncmp(str, "set", 3) == 0 && isspace(str[3])) { | 277 | if (strncmp(str, "set", 3) == 0 && isspace(str[3])) { |
277 | /* 'set xxx' was given */ | 278 | /* 'set xxx' was given */ |
278 | for (str = str + 4; isspace(*str); str++); | 279 | str = skip_spaces(str + 4); |
279 | if (strcmp(str, "on") == 0) { | 280 | if (strcmp(str, "on") == 0) { |
280 | /* switch on statistics profiling */ | 281 | /* switch on statistics profiling */ |
281 | dasd_profile_level = DASD_PROFILE_ON; | 282 | dasd_profile_level = DASD_PROFILE_ON; |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index f76f4bd82b9f..9b43ae94beba 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -1005,7 +1005,7 @@ static int dcssblk_thaw(struct device *dev) | |||
1005 | return 0; | 1005 | return 0; |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | static struct dev_pm_ops dcssblk_pm_ops = { | 1008 | static const struct dev_pm_ops dcssblk_pm_ops = { |
1009 | .freeze = dcssblk_freeze, | 1009 | .freeze = dcssblk_freeze, |
1010 | .thaw = dcssblk_thaw, | 1010 | .thaw = dcssblk_thaw, |
1011 | .restore = dcssblk_restore, | 1011 | .restore = dcssblk_restore, |
diff --git a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c index 116d1b3eeb15..118de392af63 100644 --- a/drivers/s390/block/xpram.c +++ b/drivers/s390/block/xpram.c | |||
@@ -407,7 +407,7 @@ static int xpram_restore(struct device *dev) | |||
407 | return 0; | 407 | return 0; |
408 | } | 408 | } |
409 | 409 | ||
410 | static struct dev_pm_ops xpram_pm_ops = { | 410 | static const struct dev_pm_ops xpram_pm_ops = { |
411 | .restore = xpram_restore, | 411 | .restore = xpram_restore, |
412 | }; | 412 | }; |
413 | 413 | ||
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c index 28e4649fa9e4..247b2b934728 100644 --- a/drivers/s390/char/fs3270.c +++ b/drivers/s390/char/fs3270.c | |||
@@ -467,7 +467,7 @@ fs3270_open(struct inode *inode, struct file *filp) | |||
467 | if (IS_ERR(ib)) { | 467 | if (IS_ERR(ib)) { |
468 | raw3270_put_view(&fp->view); | 468 | raw3270_put_view(&fp->view); |
469 | raw3270_del_view(&fp->view); | 469 | raw3270_del_view(&fp->view); |
470 | rc = PTR_ERR(fp); | 470 | rc = PTR_ERR(ib); |
471 | goto out; | 471 | goto out; |
472 | } | 472 | } |
473 | fp->rdbuf = ib; | 473 | fp->rdbuf = ib; |
diff --git a/drivers/s390/char/monreader.c b/drivers/s390/char/monreader.c index 60473f86e1f9..33e96484d54f 100644 --- a/drivers/s390/char/monreader.c +++ b/drivers/s390/char/monreader.c | |||
@@ -529,7 +529,7 @@ static int monreader_restore(struct device *dev) | |||
529 | return monreader_thaw(dev); | 529 | return monreader_thaw(dev); |
530 | } | 530 | } |
531 | 531 | ||
532 | static struct dev_pm_ops monreader_pm_ops = { | 532 | static const struct dev_pm_ops monreader_pm_ops = { |
533 | .freeze = monreader_freeze, | 533 | .freeze = monreader_freeze, |
534 | .thaw = monreader_thaw, | 534 | .thaw = monreader_thaw, |
535 | .restore = monreader_restore, | 535 | .restore = monreader_restore, |
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c index 6532ed8b4afa..668a0579b26b 100644 --- a/drivers/s390/char/monwriter.c +++ b/drivers/s390/char/monwriter.c | |||
@@ -323,7 +323,7 @@ static int monwriter_thaw(struct device *dev) | |||
323 | return monwriter_restore(dev); | 323 | return monwriter_restore(dev); |
324 | } | 324 | } |
325 | 325 | ||
326 | static struct dev_pm_ops monwriter_pm_ops = { | 326 | static const struct dev_pm_ops monwriter_pm_ops = { |
327 | .freeze = monwriter_freeze, | 327 | .freeze = monwriter_freeze, |
328 | .thaw = monwriter_thaw, | 328 | .thaw = monwriter_thaw, |
329 | .restore = monwriter_restore, | 329 | .restore = monwriter_restore, |
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index a983f5086788..ec88c59842e3 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c | |||
@@ -1019,7 +1019,7 @@ static int sclp_restore(struct device *dev) | |||
1019 | return sclp_undo_suspend(SCLP_PM_EVENT_RESTORE); | 1019 | return sclp_undo_suspend(SCLP_PM_EVENT_RESTORE); |
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | static struct dev_pm_ops sclp_pm_ops = { | 1022 | static const struct dev_pm_ops sclp_pm_ops = { |
1023 | .freeze = sclp_freeze, | 1023 | .freeze = sclp_freeze, |
1024 | .thaw = sclp_thaw, | 1024 | .thaw = sclp_thaw, |
1025 | .restore = sclp_restore, | 1025 | .restore = sclp_restore, |
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 28b5afc129c3..b3beab610da4 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c | |||
@@ -547,7 +547,7 @@ struct read_storage_sccb { | |||
547 | u32 entries[0]; | 547 | u32 entries[0]; |
548 | } __packed; | 548 | } __packed; |
549 | 549 | ||
550 | static struct dev_pm_ops sclp_mem_pm_ops = { | 550 | static const struct dev_pm_ops sclp_mem_pm_ops = { |
551 | .freeze = sclp_mem_freeze, | 551 | .freeze = sclp_mem_freeze, |
552 | }; | 552 | }; |
553 | 553 | ||
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 3657fe103c27..cb70fa1cf539 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define KMSG_COMPONENT "tape_34xx" | 11 | #define KMSG_COMPONENT "tape_34xx" |
12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
12 | 13 | ||
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
diff --git a/drivers/s390/char/tape_3590.c b/drivers/s390/char/tape_3590.c index 0c72aadb8391..9821c5886613 100644 --- a/drivers/s390/char/tape_3590.c +++ b/drivers/s390/char/tape_3590.c | |||
@@ -9,6 +9,7 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define KMSG_COMPONENT "tape_3590" | 11 | #define KMSG_COMPONENT "tape_3590" |
12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
12 | 13 | ||
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
@@ -136,7 +137,7 @@ static void int_to_ext_kekl(struct tape3592_kekl *in, | |||
136 | out->type_on_tape = TAPE390_KEKL_TYPE_LABEL; | 137 | out->type_on_tape = TAPE390_KEKL_TYPE_LABEL; |
137 | memcpy(out->label, in->label, sizeof(in->label)); | 138 | memcpy(out->label, in->label, sizeof(in->label)); |
138 | EBCASC(out->label, sizeof(in->label)); | 139 | EBCASC(out->label, sizeof(in->label)); |
139 | strstrip(out->label); | 140 | strim(out->label); |
140 | } | 141 | } |
141 | 142 | ||
142 | static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in, | 143 | static void int_to_ext_kekl_pair(struct tape3592_kekl_pair *in, |
diff --git a/drivers/s390/char/tape_block.c b/drivers/s390/char/tape_block.c index 4799cc2f73c3..96816149368a 100644 --- a/drivers/s390/char/tape_block.c +++ b/drivers/s390/char/tape_block.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define KMSG_COMPONENT "tape" | 13 | #define KMSG_COMPONENT "tape" |
14 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
14 | 15 | ||
15 | #include <linux/fs.h> | 16 | #include <linux/fs.h> |
16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
diff --git a/drivers/s390/char/tape_char.c b/drivers/s390/char/tape_char.c index 23d773a0d113..2125ec7d95f0 100644 --- a/drivers/s390/char/tape_char.c +++ b/drivers/s390/char/tape_char.c | |||
@@ -10,6 +10,9 @@ | |||
10 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | 10 | * Martin Schwidefsky <schwidefsky@de.ibm.com> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #define KMSG_COMPONENT "tape" | ||
14 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
15 | |||
13 | #include <linux/module.h> | 16 | #include <linux/module.h> |
14 | #include <linux/types.h> | 17 | #include <linux/types.h> |
15 | #include <linux/proc_fs.h> | 18 | #include <linux/proc_fs.h> |
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c index ddc914ccea8f..b2864e3edb6d 100644 --- a/drivers/s390/char/tape_class.c +++ b/drivers/s390/char/tape_class.c | |||
@@ -7,6 +7,10 @@ | |||
7 | * Author: Stefan Bader <shbader@de.ibm.com> | 7 | * Author: Stefan Bader <shbader@de.ibm.com> |
8 | * Based on simple class device code by Greg K-H | 8 | * Based on simple class device code by Greg K-H |
9 | */ | 9 | */ |
10 | |||
11 | #define KMSG_COMPONENT "tape" | ||
12 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
13 | |||
10 | #include "tape_class.h" | 14 | #include "tape_class.h" |
11 | 15 | ||
12 | MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>"); | 16 | MODULE_AUTHOR("Stefan Bader <shbader@de.ibm.com>"); |
diff --git a/drivers/s390/char/tape_core.c b/drivers/s390/char/tape_core.c index f5d6802dc5da..81b094e480e6 100644 --- a/drivers/s390/char/tape_core.c +++ b/drivers/s390/char/tape_core.c | |||
@@ -12,6 +12,8 @@ | |||
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define KMSG_COMPONENT "tape" | 14 | #define KMSG_COMPONENT "tape" |
15 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
16 | |||
15 | #include <linux/module.h> | 17 | #include <linux/module.h> |
16 | #include <linux/init.h> // for kernel parameters | 18 | #include <linux/init.h> // for kernel parameters |
17 | #include <linux/kmod.h> // for requesting modules | 19 | #include <linux/kmod.h> // for requesting modules |
diff --git a/drivers/s390/char/tape_proc.c b/drivers/s390/char/tape_proc.c index ebd820ccfb24..0ceb37984f77 100644 --- a/drivers/s390/char/tape_proc.c +++ b/drivers/s390/char/tape_proc.c | |||
@@ -11,6 +11,9 @@ | |||
11 | * PROCFS Functions | 11 | * PROCFS Functions |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define KMSG_COMPONENT "tape" | ||
15 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
16 | |||
14 | #include <linux/module.h> | 17 | #include <linux/module.h> |
15 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
16 | #include <linux/seq_file.h> | 19 | #include <linux/seq_file.h> |
diff --git a/drivers/s390/char/tape_std.c b/drivers/s390/char/tape_std.c index 750354ad16e5..03f07e5dd6e9 100644 --- a/drivers/s390/char/tape_std.c +++ b/drivers/s390/char/tape_std.c | |||
@@ -11,6 +11,9 @@ | |||
11 | * Stefan Bader <shbader@de.ibm.com> | 11 | * Stefan Bader <shbader@de.ibm.com> |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define KMSG_COMPONENT "tape" | ||
15 | #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt | ||
16 | |||
14 | #include <linux/stddef.h> | 17 | #include <linux/stddef.h> |
15 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
16 | #include <linux/bio.h> | 19 | #include <linux/bio.h> |
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index 899aa795bf38..7dfa5412d5a8 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c | |||
@@ -675,7 +675,7 @@ static int vmlogrdr_pm_prepare(struct device *dev) | |||
675 | } | 675 | } |
676 | 676 | ||
677 | 677 | ||
678 | static struct dev_pm_ops vmlogrdr_pm_ops = { | 678 | static const struct dev_pm_ops vmlogrdr_pm_ops = { |
679 | .prepare = vmlogrdr_pm_prepare, | 679 | .prepare = vmlogrdr_pm_prepare, |
680 | }; | 680 | }; |
681 | 681 | ||
diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index d033414f7599..e1b700a19648 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile | |||
@@ -10,5 +10,5 @@ obj-y += ccw_device.o cmf.o | |||
10 | obj-$(CONFIG_CHSC_SCH) += chsc_sch.o | 10 | obj-$(CONFIG_CHSC_SCH) += chsc_sch.o |
11 | obj-$(CONFIG_CCWGROUP) += ccwgroup.o | 11 | obj-$(CONFIG_CCWGROUP) += ccwgroup.o |
12 | 12 | ||
13 | qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_perf.o qdio_setup.o | 13 | qdio-objs := qdio_main.o qdio_thinint.o qdio_debug.o qdio_setup.o |
14 | obj-$(CONFIG_QDIO) += qdio.o | 14 | obj-$(CONFIG_QDIO) += qdio.o |
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index a5a62f1f7747..5f97ea2ee6b1 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -560,7 +560,7 @@ static int ccwgroup_pm_restore(struct device *dev) | |||
560 | return gdrv->restore ? gdrv->restore(gdev) : 0; | 560 | return gdrv->restore ? gdrv->restore(gdev) : 0; |
561 | } | 561 | } |
562 | 562 | ||
563 | static struct dev_pm_ops ccwgroup_pm_ops = { | 563 | static const struct dev_pm_ops ccwgroup_pm_ops = { |
564 | .prepare = ccwgroup_pm_prepare, | 564 | .prepare = ccwgroup_pm_prepare, |
565 | .complete = ccwgroup_pm_complete, | 565 | .complete = ccwgroup_pm_complete, |
566 | .freeze = ccwgroup_pm_freeze, | 566 | .freeze = ccwgroup_pm_freeze, |
diff --git a/drivers/s390/cio/ccwreq.c b/drivers/s390/cio/ccwreq.c index 9509e3860934..7a28a3029a3f 100644 --- a/drivers/s390/cio/ccwreq.c +++ b/drivers/s390/cio/ccwreq.c | |||
@@ -49,7 +49,6 @@ static u16 ccwreq_next_path(struct ccw_device *cdev) | |||
49 | */ | 49 | */ |
50 | static void ccwreq_stop(struct ccw_device *cdev, int rc) | 50 | static void ccwreq_stop(struct ccw_device *cdev, int rc) |
51 | { | 51 | { |
52 | struct subchannel *sch = to_subchannel(cdev->dev.parent); | ||
53 | struct ccw_request *req = &cdev->private->req; | 52 | struct ccw_request *req = &cdev->private->req; |
54 | 53 | ||
55 | if (req->done) | 54 | if (req->done) |
@@ -57,7 +56,6 @@ static void ccwreq_stop(struct ccw_device *cdev, int rc) | |||
57 | req->done = 1; | 56 | req->done = 1; |
58 | ccw_device_set_timeout(cdev, 0); | 57 | ccw_device_set_timeout(cdev, 0); |
59 | memset(&cdev->private->irb, 0, sizeof(struct irb)); | 58 | memset(&cdev->private->irb, 0, sizeof(struct irb)); |
60 | sch->lpm = sch->schib.pmcw.pam; | ||
61 | if (rc && rc != -ENODEV && req->drc) | 59 | if (rc && rc != -ENODEV && req->drc) |
62 | rc = req->drc; | 60 | rc = req->drc; |
63 | req->callback(cdev, req->data, rc); | 61 | req->callback(cdev, req->data, rc); |
@@ -80,7 +78,6 @@ static void ccwreq_do(struct ccw_device *cdev) | |||
80 | continue; | 78 | continue; |
81 | } | 79 | } |
82 | /* Perform start function. */ | 80 | /* Perform start function. */ |
83 | sch->lpm = 0xff; | ||
84 | memset(&cdev->private->irb, 0, sizeof(struct irb)); | 81 | memset(&cdev->private->irb, 0, sizeof(struct irb)); |
85 | rc = cio_start(sch, cp, (u8) req->mask); | 82 | rc = cio_start(sch, cp, (u8) req->mask); |
86 | if (rc == 0) { | 83 | if (rc == 0) { |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 92ff88ac1107..7679aee6fa14 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -1148,7 +1148,7 @@ static int css_pm_restore(struct device *dev) | |||
1148 | return drv->restore ? drv->restore(sch) : 0; | 1148 | return drv->restore ? drv->restore(sch) : 0; |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | static struct dev_pm_ops css_pm_ops = { | 1151 | static const struct dev_pm_ops css_pm_ops = { |
1152 | .prepare = css_pm_prepare, | 1152 | .prepare = css_pm_prepare, |
1153 | .complete = css_pm_complete, | 1153 | .complete = css_pm_complete, |
1154 | .freeze = css_pm_freeze, | 1154 | .freeze = css_pm_freeze, |
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 9fecfb4223a8..a6c7d5426fb2 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c | |||
@@ -1519,6 +1519,7 @@ static int ccw_device_console_enable(struct ccw_device *cdev, | |||
1519 | sch->driver = &io_subchannel_driver; | 1519 | sch->driver = &io_subchannel_driver; |
1520 | /* Initialize the ccw_device structure. */ | 1520 | /* Initialize the ccw_device structure. */ |
1521 | cdev->dev.parent= &sch->dev; | 1521 | cdev->dev.parent= &sch->dev; |
1522 | sch_set_cdev(sch, cdev); | ||
1522 | io_subchannel_recog(cdev, sch); | 1523 | io_subchannel_recog(cdev, sch); |
1523 | /* Now wait for the async. recognition to come to an end. */ | 1524 | /* Now wait for the async. recognition to come to an end. */ |
1524 | spin_lock_irq(cdev->ccwlock); | 1525 | spin_lock_irq(cdev->ccwlock); |
@@ -1904,7 +1905,7 @@ out_unlock: | |||
1904 | return ret; | 1905 | return ret; |
1905 | } | 1906 | } |
1906 | 1907 | ||
1907 | static struct dev_pm_ops ccw_pm_ops = { | 1908 | static const struct dev_pm_ops ccw_pm_ops = { |
1908 | .prepare = ccw_device_pm_prepare, | 1909 | .prepare = ccw_device_pm_prepare, |
1909 | .complete = ccw_device_pm_complete, | 1910 | .complete = ccw_device_pm_complete, |
1910 | .freeze = ccw_device_pm_freeze, | 1911 | .freeze = ccw_device_pm_freeze, |
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c index aad188e43b4f..6facb5499a65 100644 --- a/drivers/s390/cio/device_pgid.c +++ b/drivers/s390/cio/device_pgid.c | |||
@@ -142,7 +142,7 @@ static void spid_do(struct ccw_device *cdev) | |||
142 | u8 fn; | 142 | u8 fn; |
143 | 143 | ||
144 | /* Use next available path that is not already in correct state. */ | 144 | /* Use next available path that is not already in correct state. */ |
145 | req->lpm = lpm_adjust(req->lpm, sch->schib.pmcw.pam & ~sch->vpm); | 145 | req->lpm = lpm_adjust(req->lpm, cdev->private->pgid_todo_mask); |
146 | if (!req->lpm) | 146 | if (!req->lpm) |
147 | goto out_nopath; | 147 | goto out_nopath; |
148 | /* Channel program setup. */ | 148 | /* Channel program setup. */ |
@@ -254,15 +254,15 @@ static void pgid_analyze(struct ccw_device *cdev, struct pgid **p, | |||
254 | *p = first; | 254 | *p = first; |
255 | } | 255 | } |
256 | 256 | ||
257 | static u8 pgid_to_vpm(struct ccw_device *cdev) | 257 | static u8 pgid_to_donepm(struct ccw_device *cdev) |
258 | { | 258 | { |
259 | struct subchannel *sch = to_subchannel(cdev->dev.parent); | 259 | struct subchannel *sch = to_subchannel(cdev->dev.parent); |
260 | struct pgid *pgid; | 260 | struct pgid *pgid; |
261 | int i; | 261 | int i; |
262 | int lpm; | 262 | int lpm; |
263 | u8 vpm = 0; | 263 | u8 donepm = 0; |
264 | 264 | ||
265 | /* Set VPM bits for paths which are already in the target state. */ | 265 | /* Set bits for paths which are already in the target state. */ |
266 | for (i = 0; i < 8; i++) { | 266 | for (i = 0; i < 8; i++) { |
267 | lpm = 0x80 >> i; | 267 | lpm = 0x80 >> i; |
268 | if ((cdev->private->pgid_valid_mask & lpm) == 0) | 268 | if ((cdev->private->pgid_valid_mask & lpm) == 0) |
@@ -282,10 +282,10 @@ static u8 pgid_to_vpm(struct ccw_device *cdev) | |||
282 | if (pgid->inf.ps.state3 != SNID_STATE3_SINGLE_PATH) | 282 | if (pgid->inf.ps.state3 != SNID_STATE3_SINGLE_PATH) |
283 | continue; | 283 | continue; |
284 | } | 284 | } |
285 | vpm |= lpm; | 285 | donepm |= lpm; |
286 | } | 286 | } |
287 | 287 | ||
288 | return vpm; | 288 | return donepm; |
289 | } | 289 | } |
290 | 290 | ||
291 | static void pgid_fill(struct ccw_device *cdev, struct pgid *pgid) | 291 | static void pgid_fill(struct ccw_device *cdev, struct pgid *pgid) |
@@ -307,6 +307,7 @@ static void snid_done(struct ccw_device *cdev, int rc) | |||
307 | int mismatch = 0; | 307 | int mismatch = 0; |
308 | int reserved = 0; | 308 | int reserved = 0; |
309 | int reset = 0; | 309 | int reset = 0; |
310 | u8 donepm; | ||
310 | 311 | ||
311 | if (rc) | 312 | if (rc) |
312 | goto out; | 313 | goto out; |
@@ -316,18 +317,20 @@ static void snid_done(struct ccw_device *cdev, int rc) | |||
316 | else if (mismatch) | 317 | else if (mismatch) |
317 | rc = -EOPNOTSUPP; | 318 | rc = -EOPNOTSUPP; |
318 | else { | 319 | else { |
319 | sch->vpm = pgid_to_vpm(cdev); | 320 | donepm = pgid_to_donepm(cdev); |
321 | sch->vpm = donepm & sch->opm; | ||
322 | cdev->private->pgid_todo_mask &= ~donepm; | ||
320 | pgid_fill(cdev, pgid); | 323 | pgid_fill(cdev, pgid); |
321 | } | 324 | } |
322 | out: | 325 | out: |
323 | CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x " | 326 | CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x " |
324 | "mism=%d rsvd=%d reset=%d\n", id->ssid, id->devno, rc, | 327 | "todo=%02x mism=%d rsvd=%d reset=%d\n", id->ssid, |
325 | cdev->private->pgid_valid_mask, sch->vpm, mismatch, | 328 | id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm, |
326 | reserved, reset); | 329 | cdev->private->pgid_todo_mask, mismatch, reserved, reset); |
327 | switch (rc) { | 330 | switch (rc) { |
328 | case 0: | 331 | case 0: |
329 | /* Anything left to do? */ | 332 | /* Anything left to do? */ |
330 | if (sch->vpm == sch->schib.pmcw.pam) { | 333 | if (cdev->private->pgid_todo_mask == 0) { |
331 | verify_done(cdev, sch->vpm == 0 ? -EACCES : 0); | 334 | verify_done(cdev, sch->vpm == 0 ? -EACCES : 0); |
332 | return; | 335 | return; |
333 | } | 336 | } |
@@ -411,6 +414,7 @@ static void verify_start(struct ccw_device *cdev) | |||
411 | struct ccw_dev_id *devid = &cdev->private->dev_id; | 414 | struct ccw_dev_id *devid = &cdev->private->dev_id; |
412 | 415 | ||
413 | sch->vpm = 0; | 416 | sch->vpm = 0; |
417 | sch->lpm = sch->schib.pmcw.pam; | ||
414 | /* Initialize request data. */ | 418 | /* Initialize request data. */ |
415 | memset(req, 0, sizeof(*req)); | 419 | memset(req, 0, sizeof(*req)); |
416 | req->timeout = PGID_TIMEOUT; | 420 | req->timeout = PGID_TIMEOUT; |
@@ -442,11 +446,14 @@ static void verify_start(struct ccw_device *cdev) | |||
442 | */ | 446 | */ |
443 | void ccw_device_verify_start(struct ccw_device *cdev) | 447 | void ccw_device_verify_start(struct ccw_device *cdev) |
444 | { | 448 | { |
449 | struct subchannel *sch = to_subchannel(cdev->dev.parent); | ||
450 | |||
445 | CIO_TRACE_EVENT(4, "vrfy"); | 451 | CIO_TRACE_EVENT(4, "vrfy"); |
446 | CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); | 452 | CIO_HEX_EVENT(4, &cdev->private->dev_id, sizeof(cdev->private->dev_id)); |
447 | /* Initialize PGID data. */ | 453 | /* Initialize PGID data. */ |
448 | memset(cdev->private->pgid, 0, sizeof(cdev->private->pgid)); | 454 | memset(cdev->private->pgid, 0, sizeof(cdev->private->pgid)); |
449 | cdev->private->pgid_valid_mask = 0; | 455 | cdev->private->pgid_valid_mask = 0; |
456 | cdev->private->pgid_todo_mask = sch->schib.pmcw.pam; | ||
450 | /* | 457 | /* |
451 | * Initialize pathgroup and multipath state with target values. | 458 | * Initialize pathgroup and multipath state with target values. |
452 | * They may change in the course of path verification. | 459 | * They may change in the course of path verification. |
diff --git a/drivers/s390/cio/fcx.c b/drivers/s390/cio/fcx.c index 61677dfbdc9b..ca5e9bb9d458 100644 --- a/drivers/s390/cio/fcx.c +++ b/drivers/s390/cio/fcx.c | |||
@@ -163,7 +163,7 @@ void tcw_finalize(struct tcw *tcw, int num_tidaws) | |||
163 | /* Add tcat to tccb. */ | 163 | /* Add tcat to tccb. */ |
164 | tccb = tcw_get_tccb(tcw); | 164 | tccb = tcw_get_tccb(tcw); |
165 | tcat = (struct tccb_tcat *) &tccb->tca[tca_size(tccb)]; | 165 | tcat = (struct tccb_tcat *) &tccb->tca[tca_size(tccb)]; |
166 | memset(tcat, 0, sizeof(tcat)); | 166 | memset(tcat, 0, sizeof(*tcat)); |
167 | /* Calculate tcw input/output count and tcat transport count. */ | 167 | /* Calculate tcw input/output count and tcat transport count. */ |
168 | count = calc_dcw_count(tccb); | 168 | count = calc_dcw_count(tccb); |
169 | if (tcw->w && (tcw->flags & TCW_FLAGS_OUTPUT_TIDA)) | 169 | if (tcw->w && (tcw->flags & TCW_FLAGS_OUTPUT_TIDA)) |
@@ -269,7 +269,7 @@ EXPORT_SYMBOL(tccb_init); | |||
269 | */ | 269 | */ |
270 | void tsb_init(struct tsb *tsb) | 270 | void tsb_init(struct tsb *tsb) |
271 | { | 271 | { |
272 | memset(tsb, 0, sizeof(tsb)); | 272 | memset(tsb, 0, sizeof(*tsb)); |
273 | } | 273 | } |
274 | EXPORT_SYMBOL(tsb_init); | 274 | EXPORT_SYMBOL(tsb_init); |
275 | 275 | ||
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index d72ae4c93af9..b9ce712a7f25 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h | |||
@@ -150,6 +150,7 @@ struct ccw_device_private { | |||
150 | struct ccw_request req; /* internal I/O request */ | 150 | struct ccw_request req; /* internal I/O request */ |
151 | int iretry; | 151 | int iretry; |
152 | u8 pgid_valid_mask; /* mask of valid PGIDs */ | 152 | u8 pgid_valid_mask; /* mask of valid PGIDs */ |
153 | u8 pgid_todo_mask; /* mask of PGIDs to be adjusted */ | ||
153 | struct { | 154 | struct { |
154 | unsigned int fast:1; /* post with "channel end" */ | 155 | unsigned int fast:1; /* post with "channel end" */ |
155 | unsigned int repall:1; /* report every interrupt status */ | 156 | unsigned int repall:1; /* report every interrupt status */ |
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index ff7748a9199d..44f2f6a97f33 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -182,6 +182,34 @@ struct scssc_area { | |||
182 | u32:32; | 182 | u32:32; |
183 | } __attribute__ ((packed)); | 183 | } __attribute__ ((packed)); |
184 | 184 | ||
185 | struct qdio_dev_perf_stat { | ||
186 | unsigned int adapter_int; | ||
187 | unsigned int qdio_int; | ||
188 | unsigned int pci_request_int; | ||
189 | |||
190 | unsigned int tasklet_inbound; | ||
191 | unsigned int tasklet_inbound_resched; | ||
192 | unsigned int tasklet_inbound_resched2; | ||
193 | unsigned int tasklet_outbound; | ||
194 | |||
195 | unsigned int siga_read; | ||
196 | unsigned int siga_write; | ||
197 | unsigned int siga_sync; | ||
198 | |||
199 | unsigned int inbound_call; | ||
200 | unsigned int inbound_handler; | ||
201 | unsigned int stop_polling; | ||
202 | unsigned int inbound_queue_full; | ||
203 | unsigned int outbound_call; | ||
204 | unsigned int outbound_handler; | ||
205 | unsigned int fast_requeue; | ||
206 | unsigned int target_full; | ||
207 | unsigned int eqbs; | ||
208 | unsigned int eqbs_partial; | ||
209 | unsigned int sqbs; | ||
210 | unsigned int sqbs_partial; | ||
211 | }; | ||
212 | |||
185 | struct qdio_input_q { | 213 | struct qdio_input_q { |
186 | /* input buffer acknowledgement flag */ | 214 | /* input buffer acknowledgement flag */ |
187 | int polling; | 215 | int polling; |
@@ -269,6 +297,7 @@ struct qdio_irq { | |||
269 | u32 *dsci; /* address of device state change indicator */ | 297 | u32 *dsci; /* address of device state change indicator */ |
270 | struct ccw_device *cdev; | 298 | struct ccw_device *cdev; |
271 | struct dentry *debugfs_dev; | 299 | struct dentry *debugfs_dev; |
300 | struct dentry *debugfs_perf; | ||
272 | 301 | ||
273 | unsigned long int_parm; | 302 | unsigned long int_parm; |
274 | struct subchannel_id schid; | 303 | struct subchannel_id schid; |
@@ -286,9 +315,10 @@ struct qdio_irq { | |||
286 | struct ciw aqueue; | 315 | struct ciw aqueue; |
287 | 316 | ||
288 | struct qdio_ssqd_desc ssqd_desc; | 317 | struct qdio_ssqd_desc ssqd_desc; |
289 | |||
290 | void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); | 318 | void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); |
291 | 319 | ||
320 | struct qdio_dev_perf_stat perf_stat; | ||
321 | int perf_stat_enabled; | ||
292 | /* | 322 | /* |
293 | * Warning: Leave these members together at the end so they won't be | 323 | * Warning: Leave these members together at the end so they won't be |
294 | * cleared in qdio_setup_irq. | 324 | * cleared in qdio_setup_irq. |
@@ -311,6 +341,10 @@ struct qdio_irq { | |||
311 | (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ | 341 | (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ |
312 | css_general_characteristics.aif_osa) | 342 | css_general_characteristics.aif_osa) |
313 | 343 | ||
344 | #define qperf(qdev,attr) qdev->perf_stat.attr | ||
345 | #define qperf_inc(q,attr) if (q->irq_ptr->perf_stat_enabled) \ | ||
346 | q->irq_ptr->perf_stat.attr++ | ||
347 | |||
314 | /* the highest iqdio queue is used for multicast */ | 348 | /* the highest iqdio queue is used for multicast */ |
315 | static inline int multicast_outbound(struct qdio_q *q) | 349 | static inline int multicast_outbound(struct qdio_q *q) |
316 | { | 350 | { |
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index 76769978285f..f49761ff9a00 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c | |||
@@ -55,13 +55,11 @@ static int qstat_show(struct seq_file *m, void *v) | |||
55 | if (!q) | 55 | if (!q) |
56 | return 0; | 56 | return 0; |
57 | 57 | ||
58 | seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci); | 58 | seq_printf(m, "DSCI: %d nr_used: %d\n", |
59 | seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used)); | 59 | *(u32 *)q->irq_ptr->dsci, atomic_read(&q->nr_buf_used)); |
60 | seq_printf(m, "ftc: %d\n", q->first_to_check); | 60 | seq_printf(m, "ftc: %d last_move: %d\n", q->first_to_check, q->last_move); |
61 | seq_printf(m, "last_move: %d\n", q->last_move); | 61 | seq_printf(m, "polling: %d ack start: %d ack count: %d\n", |
62 | seq_printf(m, "polling: %d\n", q->u.in.polling); | 62 | q->u.in.polling, q->u.in.ack_start, q->u.in.ack_count); |
63 | seq_printf(m, "ack start: %d\n", q->u.in.ack_start); | ||
64 | seq_printf(m, "ack count: %d\n", q->u.in.ack_count); | ||
65 | seq_printf(m, "slsb buffer states:\n"); | 63 | seq_printf(m, "slsb buffer states:\n"); |
66 | seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n"); | 64 | seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n"); |
67 | 65 | ||
@@ -110,7 +108,6 @@ static ssize_t qstat_seq_write(struct file *file, const char __user *buf, | |||
110 | 108 | ||
111 | if (!q) | 109 | if (!q) |
112 | return 0; | 110 | return 0; |
113 | |||
114 | if (q->is_input_q) | 111 | if (q->is_input_q) |
115 | xchg(q->irq_ptr->dsci, 1); | 112 | xchg(q->irq_ptr->dsci, 1); |
116 | local_bh_disable(); | 113 | local_bh_disable(); |
@@ -134,6 +131,98 @@ static const struct file_operations debugfs_fops = { | |||
134 | .release = single_release, | 131 | .release = single_release, |
135 | }; | 132 | }; |
136 | 133 | ||
134 | static char *qperf_names[] = { | ||
135 | "Assumed adapter interrupts", | ||
136 | "QDIO interrupts", | ||
137 | "Requested PCIs", | ||
138 | "Inbound tasklet runs", | ||
139 | "Inbound tasklet resched", | ||
140 | "Inbound tasklet resched2", | ||
141 | "Outbound tasklet runs", | ||
142 | "SIGA read", | ||
143 | "SIGA write", | ||
144 | "SIGA sync", | ||
145 | "Inbound calls", | ||
146 | "Inbound handler", | ||
147 | "Inbound stop_polling", | ||
148 | "Inbound queue full", | ||
149 | "Outbound calls", | ||
150 | "Outbound handler", | ||
151 | "Outbound fast_requeue", | ||
152 | "Outbound target_full", | ||
153 | "QEBSM eqbs", | ||
154 | "QEBSM eqbs partial", | ||
155 | "QEBSM sqbs", | ||
156 | "QEBSM sqbs partial" | ||
157 | }; | ||
158 | |||
159 | static int qperf_show(struct seq_file *m, void *v) | ||
160 | { | ||
161 | struct qdio_irq *irq_ptr = m->private; | ||
162 | unsigned int *stat; | ||
163 | int i; | ||
164 | |||
165 | if (!irq_ptr) | ||
166 | return 0; | ||
167 | if (!irq_ptr->perf_stat_enabled) { | ||
168 | seq_printf(m, "disabled\n"); | ||
169 | return 0; | ||
170 | } | ||
171 | stat = (unsigned int *)&irq_ptr->perf_stat; | ||
172 | |||
173 | for (i = 0; i < ARRAY_SIZE(qperf_names); i++) | ||
174 | seq_printf(m, "%26s:\t%u\n", | ||
175 | qperf_names[i], *(stat + i)); | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf, | ||
180 | size_t count, loff_t *off) | ||
181 | { | ||
182 | struct seq_file *seq = file->private_data; | ||
183 | struct qdio_irq *irq_ptr = seq->private; | ||
184 | unsigned long val; | ||
185 | char buf[8]; | ||
186 | int ret; | ||
187 | |||
188 | if (!irq_ptr) | ||
189 | return 0; | ||
190 | if (count >= sizeof(buf)) | ||
191 | return -EINVAL; | ||
192 | if (copy_from_user(&buf, ubuf, count)) | ||
193 | return -EFAULT; | ||
194 | buf[count] = 0; | ||
195 | |||
196 | ret = strict_strtoul(buf, 10, &val); | ||
197 | if (ret < 0) | ||
198 | return ret; | ||
199 | |||
200 | switch (val) { | ||
201 | case 0: | ||
202 | irq_ptr->perf_stat_enabled = 0; | ||
203 | memset(&irq_ptr->perf_stat, 0, sizeof(irq_ptr->perf_stat)); | ||
204 | break; | ||
205 | case 1: | ||
206 | irq_ptr->perf_stat_enabled = 1; | ||
207 | break; | ||
208 | } | ||
209 | return count; | ||
210 | } | ||
211 | |||
212 | static int qperf_seq_open(struct inode *inode, struct file *filp) | ||
213 | { | ||
214 | return single_open(filp, qperf_show, | ||
215 | filp->f_path.dentry->d_inode->i_private); | ||
216 | } | ||
217 | |||
218 | static struct file_operations debugfs_perf_fops = { | ||
219 | .owner = THIS_MODULE, | ||
220 | .open = qperf_seq_open, | ||
221 | .read = seq_read, | ||
222 | .write = qperf_seq_write, | ||
223 | .llseek = seq_lseek, | ||
224 | .release = single_release, | ||
225 | }; | ||
137 | static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev) | 226 | static void setup_debugfs_entry(struct qdio_q *q, struct ccw_device *cdev) |
138 | { | 227 | { |
139 | char name[QDIO_DEBUGFS_NAME_LEN]; | 228 | char name[QDIO_DEBUGFS_NAME_LEN]; |
@@ -156,6 +245,14 @@ void qdio_setup_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cdev) | |||
156 | debugfs_root); | 245 | debugfs_root); |
157 | if (IS_ERR(irq_ptr->debugfs_dev)) | 246 | if (IS_ERR(irq_ptr->debugfs_dev)) |
158 | irq_ptr->debugfs_dev = NULL; | 247 | irq_ptr->debugfs_dev = NULL; |
248 | |||
249 | irq_ptr->debugfs_perf = debugfs_create_file("statistics", | ||
250 | S_IFREG | S_IRUGO | S_IWUSR, | ||
251 | irq_ptr->debugfs_dev, irq_ptr, | ||
252 | &debugfs_perf_fops); | ||
253 | if (IS_ERR(irq_ptr->debugfs_perf)) | ||
254 | irq_ptr->debugfs_perf = NULL; | ||
255 | |||
159 | for_each_input_queue(irq_ptr, q, i) | 256 | for_each_input_queue(irq_ptr, q, i) |
160 | setup_debugfs_entry(q, cdev); | 257 | setup_debugfs_entry(q, cdev); |
161 | for_each_output_queue(irq_ptr, q, i) | 258 | for_each_output_queue(irq_ptr, q, i) |
@@ -171,6 +268,7 @@ void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr, struct ccw_device *cd | |||
171 | debugfs_remove(q->debugfs_q); | 268 | debugfs_remove(q->debugfs_q); |
172 | for_each_output_queue(irq_ptr, q, i) | 269 | for_each_output_queue(irq_ptr, q, i) |
173 | debugfs_remove(q->debugfs_q); | 270 | debugfs_remove(q->debugfs_q); |
271 | debugfs_remove(irq_ptr->debugfs_perf); | ||
174 | debugfs_remove(irq_ptr->debugfs_dev); | 272 | debugfs_remove(irq_ptr->debugfs_dev); |
175 | } | 273 | } |
176 | 274 | ||
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 4be6e84b9599..999fe80c4051 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include "device.h" | 22 | #include "device.h" |
23 | #include "qdio.h" | 23 | #include "qdio.h" |
24 | #include "qdio_debug.h" | 24 | #include "qdio_debug.h" |
25 | #include "qdio_perf.h" | ||
26 | 25 | ||
27 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>,"\ | 26 | MODULE_AUTHOR("Utz Bacher <utz.bacher@de.ibm.com>,"\ |
28 | "Jan Glauber <jang@linux.vnet.ibm.com>"); | 27 | "Jan Glauber <jang@linux.vnet.ibm.com>"); |
@@ -126,7 +125,7 @@ static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state, | |||
126 | int rc; | 125 | int rc; |
127 | 126 | ||
128 | BUG_ON(!q->irq_ptr->sch_token); | 127 | BUG_ON(!q->irq_ptr->sch_token); |
129 | qdio_perf_stat_inc(&perf_stats.debug_eqbs_all); | 128 | qperf_inc(q, eqbs); |
130 | 129 | ||
131 | if (!q->is_input_q) | 130 | if (!q->is_input_q) |
132 | nr += q->irq_ptr->nr_input_qs; | 131 | nr += q->irq_ptr->nr_input_qs; |
@@ -139,7 +138,7 @@ again: | |||
139 | * buffers later. | 138 | * buffers later. |
140 | */ | 139 | */ |
141 | if ((ccq == 96) && (count != tmp_count)) { | 140 | if ((ccq == 96) && (count != tmp_count)) { |
142 | qdio_perf_stat_inc(&perf_stats.debug_eqbs_incomplete); | 141 | qperf_inc(q, eqbs_partial); |
143 | return (count - tmp_count); | 142 | return (count - tmp_count); |
144 | } | 143 | } |
145 | 144 | ||
@@ -182,7 +181,7 @@ static int qdio_do_sqbs(struct qdio_q *q, unsigned char state, int start, | |||
182 | return 0; | 181 | return 0; |
183 | 182 | ||
184 | BUG_ON(!q->irq_ptr->sch_token); | 183 | BUG_ON(!q->irq_ptr->sch_token); |
185 | qdio_perf_stat_inc(&perf_stats.debug_sqbs_all); | 184 | qperf_inc(q, sqbs); |
186 | 185 | ||
187 | if (!q->is_input_q) | 186 | if (!q->is_input_q) |
188 | nr += q->irq_ptr->nr_input_qs; | 187 | nr += q->irq_ptr->nr_input_qs; |
@@ -191,7 +190,7 @@ again: | |||
191 | rc = qdio_check_ccq(q, ccq); | 190 | rc = qdio_check_ccq(q, ccq); |
192 | if (rc == 1) { | 191 | if (rc == 1) { |
193 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq); | 192 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq); |
194 | qdio_perf_stat_inc(&perf_stats.debug_sqbs_incomplete); | 193 | qperf_inc(q, sqbs_partial); |
195 | goto again; | 194 | goto again; |
196 | } | 195 | } |
197 | if (rc < 0) { | 196 | if (rc < 0) { |
@@ -285,7 +284,7 @@ static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output, | |||
285 | return 0; | 284 | return 0; |
286 | 285 | ||
287 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr); | 286 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-s:%1d", q->nr); |
288 | qdio_perf_stat_inc(&perf_stats.siga_sync); | 287 | qperf_inc(q, siga_sync); |
289 | 288 | ||
290 | cc = do_siga_sync(q->irq_ptr->schid, output, input); | 289 | cc = do_siga_sync(q->irq_ptr->schid, output, input); |
291 | if (cc) | 290 | if (cc) |
@@ -350,7 +349,7 @@ static inline int qdio_siga_input(struct qdio_q *q) | |||
350 | int cc; | 349 | int cc; |
351 | 350 | ||
352 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-r:%1d", q->nr); | 351 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-r:%1d", q->nr); |
353 | qdio_perf_stat_inc(&perf_stats.siga_in); | 352 | qperf_inc(q, siga_read); |
354 | 353 | ||
355 | cc = do_siga_input(q->irq_ptr->schid, q->mask); | 354 | cc = do_siga_input(q->irq_ptr->schid, q->mask); |
356 | if (cc) | 355 | if (cc) |
@@ -382,7 +381,7 @@ static inline void qdio_stop_polling(struct qdio_q *q) | |||
382 | return; | 381 | return; |
383 | 382 | ||
384 | q->u.in.polling = 0; | 383 | q->u.in.polling = 0; |
385 | qdio_perf_stat_inc(&perf_stats.debug_stop_polling); | 384 | qperf_inc(q, stop_polling); |
386 | 385 | ||
387 | /* show the card that we are not polling anymore */ | 386 | /* show the card that we are not polling anymore */ |
388 | if (is_qebsm(q)) { | 387 | if (is_qebsm(q)) { |
@@ -400,7 +399,7 @@ static void announce_buffer_error(struct qdio_q *q, int count) | |||
400 | /* special handling for no target buffer empty */ | 399 | /* special handling for no target buffer empty */ |
401 | if ((!q->is_input_q && | 400 | if ((!q->is_input_q && |
402 | (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) { | 401 | (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) { |
403 | qdio_perf_stat_inc(&perf_stats.outbound_target_full); | 402 | qperf_inc(q, target_full); |
404 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x", | 403 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x", |
405 | q->first_to_check); | 404 | q->first_to_check); |
406 | return; | 405 | return; |
@@ -486,7 +485,8 @@ static int get_inbound_buffer_frontier(struct qdio_q *q) | |||
486 | case SLSB_P_INPUT_PRIMED: | 485 | case SLSB_P_INPUT_PRIMED: |
487 | inbound_primed(q, count); | 486 | inbound_primed(q, count); |
488 | q->first_to_check = add_buf(q->first_to_check, count); | 487 | q->first_to_check = add_buf(q->first_to_check, count); |
489 | atomic_sub(count, &q->nr_buf_used); | 488 | if (atomic_sub(count, &q->nr_buf_used) == 0) |
489 | qperf_inc(q, inbound_queue_full); | ||
490 | break; | 490 | break; |
491 | case SLSB_P_INPUT_ERROR: | 491 | case SLSB_P_INPUT_ERROR: |
492 | announce_buffer_error(q, count); | 492 | announce_buffer_error(q, count); |
@@ -566,9 +566,10 @@ static void qdio_kick_handler(struct qdio_q *q) | |||
566 | count = sub_buf(end, start); | 566 | count = sub_buf(end, start); |
567 | 567 | ||
568 | if (q->is_input_q) { | 568 | if (q->is_input_q) { |
569 | qdio_perf_stat_inc(&perf_stats.inbound_handler); | 569 | qperf_inc(q, inbound_handler); |
570 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); | 570 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); |
571 | } else | 571 | } else |
572 | qperf_inc(q, outbound_handler); | ||
572 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", | 573 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x", |
573 | start, count); | 574 | start, count); |
574 | 575 | ||
@@ -582,24 +583,28 @@ static void qdio_kick_handler(struct qdio_q *q) | |||
582 | 583 | ||
583 | static void __qdio_inbound_processing(struct qdio_q *q) | 584 | static void __qdio_inbound_processing(struct qdio_q *q) |
584 | { | 585 | { |
585 | qdio_perf_stat_inc(&perf_stats.tasklet_inbound); | 586 | qperf_inc(q, tasklet_inbound); |
586 | again: | 587 | again: |
587 | if (!qdio_inbound_q_moved(q)) | 588 | if (!qdio_inbound_q_moved(q)) |
588 | return; | 589 | return; |
589 | 590 | ||
590 | qdio_kick_handler(q); | 591 | qdio_kick_handler(q); |
591 | 592 | ||
592 | if (!qdio_inbound_q_done(q)) | 593 | if (!qdio_inbound_q_done(q)) { |
593 | /* means poll time is not yet over */ | 594 | /* means poll time is not yet over */ |
595 | qperf_inc(q, tasklet_inbound_resched); | ||
594 | goto again; | 596 | goto again; |
597 | } | ||
595 | 598 | ||
596 | qdio_stop_polling(q); | 599 | qdio_stop_polling(q); |
597 | /* | 600 | /* |
598 | * We need to check again to not lose initiative after | 601 | * We need to check again to not lose initiative after |
599 | * resetting the ACK state. | 602 | * resetting the ACK state. |
600 | */ | 603 | */ |
601 | if (!qdio_inbound_q_done(q)) | 604 | if (!qdio_inbound_q_done(q)) { |
605 | qperf_inc(q, tasklet_inbound_resched2); | ||
602 | goto again; | 606 | goto again; |
607 | } | ||
603 | } | 608 | } |
604 | 609 | ||
605 | void qdio_inbound_processing(unsigned long data) | 610 | void qdio_inbound_processing(unsigned long data) |
@@ -687,7 +692,7 @@ static int qdio_kick_outbound_q(struct qdio_q *q) | |||
687 | return 0; | 692 | return 0; |
688 | 693 | ||
689 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); | 694 | DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); |
690 | qdio_perf_stat_inc(&perf_stats.siga_out); | 695 | qperf_inc(q, siga_write); |
691 | 696 | ||
692 | cc = qdio_siga_output(q, &busy_bit); | 697 | cc = qdio_siga_output(q, &busy_bit); |
693 | switch (cc) { | 698 | switch (cc) { |
@@ -710,7 +715,7 @@ static int qdio_kick_outbound_q(struct qdio_q *q) | |||
710 | 715 | ||
711 | static void __qdio_outbound_processing(struct qdio_q *q) | 716 | static void __qdio_outbound_processing(struct qdio_q *q) |
712 | { | 717 | { |
713 | qdio_perf_stat_inc(&perf_stats.tasklet_outbound); | 718 | qperf_inc(q, tasklet_outbound); |
714 | BUG_ON(atomic_read(&q->nr_buf_used) < 0); | 719 | BUG_ON(atomic_read(&q->nr_buf_used) < 0); |
715 | 720 | ||
716 | if (qdio_outbound_q_moved(q)) | 721 | if (qdio_outbound_q_moved(q)) |
@@ -738,12 +743,9 @@ static void __qdio_outbound_processing(struct qdio_q *q) | |||
738 | */ | 743 | */ |
739 | if (qdio_outbound_q_done(q)) | 744 | if (qdio_outbound_q_done(q)) |
740 | del_timer(&q->u.out.timer); | 745 | del_timer(&q->u.out.timer); |
741 | else { | 746 | else |
742 | if (!timer_pending(&q->u.out.timer)) { | 747 | if (!timer_pending(&q->u.out.timer)) |
743 | mod_timer(&q->u.out.timer, jiffies + 10 * HZ); | 748 | mod_timer(&q->u.out.timer, jiffies + 10 * HZ); |
744 | qdio_perf_stat_inc(&perf_stats.debug_tl_out_timer); | ||
745 | } | ||
746 | } | ||
747 | return; | 749 | return; |
748 | 750 | ||
749 | sched: | 751 | sched: |
@@ -783,7 +785,7 @@ static inline void qdio_check_outbound_after_thinint(struct qdio_q *q) | |||
783 | 785 | ||
784 | static void __tiqdio_inbound_processing(struct qdio_q *q) | 786 | static void __tiqdio_inbound_processing(struct qdio_q *q) |
785 | { | 787 | { |
786 | qdio_perf_stat_inc(&perf_stats.thinint_inbound); | 788 | qperf_inc(q, tasklet_inbound); |
787 | qdio_sync_after_thinint(q); | 789 | qdio_sync_after_thinint(q); |
788 | 790 | ||
789 | /* | 791 | /* |
@@ -798,7 +800,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q) | |||
798 | qdio_kick_handler(q); | 800 | qdio_kick_handler(q); |
799 | 801 | ||
800 | if (!qdio_inbound_q_done(q)) { | 802 | if (!qdio_inbound_q_done(q)) { |
801 | qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop); | 803 | qperf_inc(q, tasklet_inbound_resched); |
802 | if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) { | 804 | if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) { |
803 | tasklet_schedule(&q->tasklet); | 805 | tasklet_schedule(&q->tasklet); |
804 | return; | 806 | return; |
@@ -811,7 +813,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q) | |||
811 | * resetting the ACK state. | 813 | * resetting the ACK state. |
812 | */ | 814 | */ |
813 | if (!qdio_inbound_q_done(q)) { | 815 | if (!qdio_inbound_q_done(q)) { |
814 | qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2); | 816 | qperf_inc(q, tasklet_inbound_resched2); |
815 | if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) | 817 | if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED)) |
816 | tasklet_schedule(&q->tasklet); | 818 | tasklet_schedule(&q->tasklet); |
817 | } | 819 | } |
@@ -850,8 +852,6 @@ static void qdio_int_handler_pci(struct qdio_irq *irq_ptr) | |||
850 | if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) | 852 | if (unlikely(irq_ptr->state == QDIO_IRQ_STATE_STOPPED)) |
851 | return; | 853 | return; |
852 | 854 | ||
853 | qdio_perf_stat_inc(&perf_stats.pci_int); | ||
854 | |||
855 | for_each_input_queue(irq_ptr, q, i) | 855 | for_each_input_queue(irq_ptr, q, i) |
856 | tasklet_schedule(&q->tasklet); | 856 | tasklet_schedule(&q->tasklet); |
857 | 857 | ||
@@ -922,8 +922,6 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, | |||
922 | struct qdio_irq *irq_ptr = cdev->private->qdio_data; | 922 | struct qdio_irq *irq_ptr = cdev->private->qdio_data; |
923 | int cstat, dstat; | 923 | int cstat, dstat; |
924 | 924 | ||
925 | qdio_perf_stat_inc(&perf_stats.qdio_int); | ||
926 | |||
927 | if (!intparm || !irq_ptr) { | 925 | if (!intparm || !irq_ptr) { |
928 | DBF_ERROR("qint:%4x", cdev->private->schid.sch_no); | 926 | DBF_ERROR("qint:%4x", cdev->private->schid.sch_no); |
929 | return; | 927 | return; |
@@ -1382,6 +1380,8 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags, | |||
1382 | { | 1380 | { |
1383 | int used, diff; | 1381 | int used, diff; |
1384 | 1382 | ||
1383 | qperf_inc(q, inbound_call); | ||
1384 | |||
1385 | if (!q->u.in.polling) | 1385 | if (!q->u.in.polling) |
1386 | goto set; | 1386 | goto set; |
1387 | 1387 | ||
@@ -1437,14 +1437,16 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags, | |||
1437 | unsigned char state; | 1437 | unsigned char state; |
1438 | int used, rc = 0; | 1438 | int used, rc = 0; |
1439 | 1439 | ||
1440 | qdio_perf_stat_inc(&perf_stats.outbound_handler); | 1440 | qperf_inc(q, outbound_call); |
1441 | 1441 | ||
1442 | count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count); | 1442 | count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count); |
1443 | used = atomic_add_return(count, &q->nr_buf_used); | 1443 | used = atomic_add_return(count, &q->nr_buf_used); |
1444 | BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q); | 1444 | BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q); |
1445 | 1445 | ||
1446 | if (callflags & QDIO_FLAG_PCI_OUT) | 1446 | if (callflags & QDIO_FLAG_PCI_OUT) { |
1447 | q->u.out.pci_out_enabled = 1; | 1447 | q->u.out.pci_out_enabled = 1; |
1448 | qperf_inc(q, pci_request_int); | ||
1449 | } | ||
1448 | else | 1450 | else |
1449 | q->u.out.pci_out_enabled = 0; | 1451 | q->u.out.pci_out_enabled = 0; |
1450 | 1452 | ||
@@ -1483,7 +1485,7 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags, | |||
1483 | if (state != SLSB_CU_OUTPUT_PRIMED) | 1485 | if (state != SLSB_CU_OUTPUT_PRIMED) |
1484 | rc = qdio_kick_outbound_q(q); | 1486 | rc = qdio_kick_outbound_q(q); |
1485 | else | 1487 | else |
1486 | qdio_perf_stat_inc(&perf_stats.fast_requeue); | 1488 | qperf_inc(q, fast_requeue); |
1487 | 1489 | ||
1488 | out: | 1490 | out: |
1489 | tasklet_schedule(&q->tasklet); | 1491 | tasklet_schedule(&q->tasklet); |
@@ -1539,16 +1541,11 @@ static int __init init_QDIO(void) | |||
1539 | rc = qdio_debug_init(); | 1541 | rc = qdio_debug_init(); |
1540 | if (rc) | 1542 | if (rc) |
1541 | goto out_ti; | 1543 | goto out_ti; |
1542 | rc = qdio_setup_perf_stats(); | ||
1543 | if (rc) | ||
1544 | goto out_debug; | ||
1545 | rc = tiqdio_register_thinints(); | 1544 | rc = tiqdio_register_thinints(); |
1546 | if (rc) | 1545 | if (rc) |
1547 | goto out_perf; | 1546 | goto out_debug; |
1548 | return 0; | 1547 | return 0; |
1549 | 1548 | ||
1550 | out_perf: | ||
1551 | qdio_remove_perf_stats(); | ||
1552 | out_debug: | 1549 | out_debug: |
1553 | qdio_debug_exit(); | 1550 | qdio_debug_exit(); |
1554 | out_ti: | 1551 | out_ti: |
@@ -1562,7 +1559,6 @@ static void __exit exit_QDIO(void) | |||
1562 | { | 1559 | { |
1563 | tiqdio_unregister_thinints(); | 1560 | tiqdio_unregister_thinints(); |
1564 | tiqdio_free_memory(); | 1561 | tiqdio_free_memory(); |
1565 | qdio_remove_perf_stats(); | ||
1566 | qdio_debug_exit(); | 1562 | qdio_debug_exit(); |
1567 | qdio_setup_exit(); | 1563 | qdio_setup_exit(); |
1568 | } | 1564 | } |
diff --git a/drivers/s390/cio/qdio_perf.c b/drivers/s390/cio/qdio_perf.c deleted file mode 100644 index 968e3c7c2632..000000000000 --- a/drivers/s390/cio/qdio_perf.c +++ /dev/null | |||
@@ -1,147 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/s390/cio/qdio_perf.c | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | ||
5 | * | ||
6 | * Author: Jan Glauber (jang@linux.vnet.ibm.com) | ||
7 | */ | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/proc_fs.h> | ||
10 | #include <linux/seq_file.h> | ||
11 | #include <asm/ccwdev.h> | ||
12 | |||
13 | #include "cio.h" | ||
14 | #include "css.h" | ||
15 | #include "device.h" | ||
16 | #include "ioasm.h" | ||
17 | #include "chsc.h" | ||
18 | #include "qdio_debug.h" | ||
19 | #include "qdio_perf.h" | ||
20 | |||
21 | int qdio_performance_stats; | ||
22 | struct qdio_perf_stats perf_stats; | ||
23 | |||
24 | #ifdef CONFIG_PROC_FS | ||
25 | static struct proc_dir_entry *qdio_perf_pde; | ||
26 | #endif | ||
27 | |||
28 | /* | ||
29 | * procfs functions | ||
30 | */ | ||
31 | static int qdio_perf_proc_show(struct seq_file *m, void *v) | ||
32 | { | ||
33 | seq_printf(m, "Number of qdio interrupts\t\t\t: %li\n", | ||
34 | (long)atomic_long_read(&perf_stats.qdio_int)); | ||
35 | seq_printf(m, "Number of PCI interrupts\t\t\t: %li\n", | ||
36 | (long)atomic_long_read(&perf_stats.pci_int)); | ||
37 | seq_printf(m, "Number of adapter interrupts\t\t\t: %li\n", | ||
38 | (long)atomic_long_read(&perf_stats.thin_int)); | ||
39 | seq_printf(m, "\n"); | ||
40 | seq_printf(m, "Inbound tasklet runs\t\t\t\t: %li\n", | ||
41 | (long)atomic_long_read(&perf_stats.tasklet_inbound)); | ||
42 | seq_printf(m, "Outbound tasklet runs\t\t\t\t: %li\n", | ||
43 | (long)atomic_long_read(&perf_stats.tasklet_outbound)); | ||
44 | seq_printf(m, "Adapter interrupt tasklet runs/loops\t\t: %li/%li\n", | ||
45 | (long)atomic_long_read(&perf_stats.tasklet_thinint), | ||
46 | (long)atomic_long_read(&perf_stats.tasklet_thinint_loop)); | ||
47 | seq_printf(m, "Adapter interrupt inbound tasklet runs/loops\t: %li/%li\n", | ||
48 | (long)atomic_long_read(&perf_stats.thinint_inbound), | ||
49 | (long)atomic_long_read(&perf_stats.thinint_inbound_loop)); | ||
50 | seq_printf(m, "\n"); | ||
51 | seq_printf(m, "Number of SIGA In issued\t\t\t: %li\n", | ||
52 | (long)atomic_long_read(&perf_stats.siga_in)); | ||
53 | seq_printf(m, "Number of SIGA Out issued\t\t\t: %li\n", | ||
54 | (long)atomic_long_read(&perf_stats.siga_out)); | ||
55 | seq_printf(m, "Number of SIGA Sync issued\t\t\t: %li\n", | ||
56 | (long)atomic_long_read(&perf_stats.siga_sync)); | ||
57 | seq_printf(m, "\n"); | ||
58 | seq_printf(m, "Number of inbound transfers\t\t\t: %li\n", | ||
59 | (long)atomic_long_read(&perf_stats.inbound_handler)); | ||
60 | seq_printf(m, "Number of outbound transfers\t\t\t: %li\n", | ||
61 | (long)atomic_long_read(&perf_stats.outbound_handler)); | ||
62 | seq_printf(m, "\n"); | ||
63 | seq_printf(m, "Number of fast requeues (outg. SBAL w/o SIGA)\t: %li\n", | ||
64 | (long)atomic_long_read(&perf_stats.fast_requeue)); | ||
65 | seq_printf(m, "Number of outbound target full condition\t: %li\n", | ||
66 | (long)atomic_long_read(&perf_stats.outbound_target_full)); | ||
67 | seq_printf(m, "Number of outbound tasklet mod_timer calls\t: %li\n", | ||
68 | (long)atomic_long_read(&perf_stats.debug_tl_out_timer)); | ||
69 | seq_printf(m, "Number of stop polling calls\t\t\t: %li\n", | ||
70 | (long)atomic_long_read(&perf_stats.debug_stop_polling)); | ||
71 | seq_printf(m, "AI inbound tasklet loops after stop polling\t: %li\n", | ||
72 | (long)atomic_long_read(&perf_stats.thinint_inbound_loop2)); | ||
73 | seq_printf(m, "QEBSM EQBS total/incomplete\t\t\t: %li/%li\n", | ||
74 | (long)atomic_long_read(&perf_stats.debug_eqbs_all), | ||
75 | (long)atomic_long_read(&perf_stats.debug_eqbs_incomplete)); | ||
76 | seq_printf(m, "QEBSM SQBS total/incomplete\t\t\t: %li/%li\n", | ||
77 | (long)atomic_long_read(&perf_stats.debug_sqbs_all), | ||
78 | (long)atomic_long_read(&perf_stats.debug_sqbs_incomplete)); | ||
79 | seq_printf(m, "\n"); | ||
80 | return 0; | ||
81 | } | ||
82 | static int qdio_perf_seq_open(struct inode *inode, struct file *filp) | ||
83 | { | ||
84 | return single_open(filp, qdio_perf_proc_show, NULL); | ||
85 | } | ||
86 | |||
87 | static const struct file_operations qdio_perf_proc_fops = { | ||
88 | .owner = THIS_MODULE, | ||
89 | .open = qdio_perf_seq_open, | ||
90 | .read = seq_read, | ||
91 | .llseek = seq_lseek, | ||
92 | .release = single_release, | ||
93 | }; | ||
94 | |||
95 | /* | ||
96 | * sysfs functions | ||
97 | */ | ||
98 | static ssize_t qdio_perf_stats_show(struct bus_type *bus, char *buf) | ||
99 | { | ||
100 | return sprintf(buf, "%i\n", qdio_performance_stats ? 1 : 0); | ||
101 | } | ||
102 | |||
103 | static ssize_t qdio_perf_stats_store(struct bus_type *bus, | ||
104 | const char *buf, size_t count) | ||
105 | { | ||
106 | unsigned long i; | ||
107 | |||
108 | if (strict_strtoul(buf, 16, &i) != 0) | ||
109 | return -EINVAL; | ||
110 | if ((i != 0) && (i != 1)) | ||
111 | return -EINVAL; | ||
112 | if (i == qdio_performance_stats) | ||
113 | return count; | ||
114 | |||
115 | qdio_performance_stats = i; | ||
116 | /* reset performance statistics */ | ||
117 | if (i == 0) | ||
118 | memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); | ||
119 | return count; | ||
120 | } | ||
121 | |||
122 | static BUS_ATTR(qdio_performance_stats, 0644, qdio_perf_stats_show, | ||
123 | qdio_perf_stats_store); | ||
124 | |||
125 | int __init qdio_setup_perf_stats(void) | ||
126 | { | ||
127 | int rc; | ||
128 | |||
129 | rc = bus_create_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); | ||
130 | if (rc) | ||
131 | return rc; | ||
132 | |||
133 | #ifdef CONFIG_PROC_FS | ||
134 | memset(&perf_stats, 0, sizeof(struct qdio_perf_stats)); | ||
135 | qdio_perf_pde = proc_create("qdio_perf", S_IFREG | S_IRUGO, | ||
136 | NULL, &qdio_perf_proc_fops); | ||
137 | #endif | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | void qdio_remove_perf_stats(void) | ||
142 | { | ||
143 | #ifdef CONFIG_PROC_FS | ||
144 | remove_proc_entry("qdio_perf", NULL); | ||
145 | #endif | ||
146 | bus_remove_file(&ccw_bus_type, &bus_attr_qdio_performance_stats); | ||
147 | } | ||
diff --git a/drivers/s390/cio/qdio_perf.h b/drivers/s390/cio/qdio_perf.h deleted file mode 100644 index ff4504ce1e3c..000000000000 --- a/drivers/s390/cio/qdio_perf.h +++ /dev/null | |||
@@ -1,61 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/s390/cio/qdio_perf.h | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | ||
5 | * | ||
6 | * Author: Jan Glauber (jang@linux.vnet.ibm.com) | ||
7 | */ | ||
8 | #ifndef QDIO_PERF_H | ||
9 | #define QDIO_PERF_H | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <asm/atomic.h> | ||
13 | |||
14 | struct qdio_perf_stats { | ||
15 | /* interrupt handler calls */ | ||
16 | atomic_long_t qdio_int; | ||
17 | atomic_long_t pci_int; | ||
18 | atomic_long_t thin_int; | ||
19 | |||
20 | /* tasklet runs */ | ||
21 | atomic_long_t tasklet_inbound; | ||
22 | atomic_long_t tasklet_outbound; | ||
23 | atomic_long_t tasklet_thinint; | ||
24 | atomic_long_t tasklet_thinint_loop; | ||
25 | atomic_long_t thinint_inbound; | ||
26 | atomic_long_t thinint_inbound_loop; | ||
27 | atomic_long_t thinint_inbound_loop2; | ||
28 | |||
29 | /* signal adapter calls */ | ||
30 | atomic_long_t siga_out; | ||
31 | atomic_long_t siga_in; | ||
32 | atomic_long_t siga_sync; | ||
33 | |||
34 | /* misc */ | ||
35 | atomic_long_t inbound_handler; | ||
36 | atomic_long_t outbound_handler; | ||
37 | atomic_long_t fast_requeue; | ||
38 | atomic_long_t outbound_target_full; | ||
39 | |||
40 | /* for debugging */ | ||
41 | atomic_long_t debug_tl_out_timer; | ||
42 | atomic_long_t debug_stop_polling; | ||
43 | atomic_long_t debug_eqbs_all; | ||
44 | atomic_long_t debug_eqbs_incomplete; | ||
45 | atomic_long_t debug_sqbs_all; | ||
46 | atomic_long_t debug_sqbs_incomplete; | ||
47 | }; | ||
48 | |||
49 | extern struct qdio_perf_stats perf_stats; | ||
50 | extern int qdio_performance_stats; | ||
51 | |||
52 | static inline void qdio_perf_stat_inc(atomic_long_t *count) | ||
53 | { | ||
54 | if (qdio_performance_stats) | ||
55 | atomic_long_inc(count); | ||
56 | } | ||
57 | |||
58 | int qdio_setup_perf_stats(void); | ||
59 | void qdio_remove_perf_stats(void); | ||
60 | |||
61 | #endif | ||
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 18d54fc21ce9..8c2dea5fa2b4 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c | |||
@@ -48,7 +48,6 @@ static void set_impl_params(struct qdio_irq *irq_ptr, | |||
48 | if (!irq_ptr) | 48 | if (!irq_ptr) |
49 | return; | 49 | return; |
50 | 50 | ||
51 | WARN_ON((unsigned long)&irq_ptr->qib & 0xff); | ||
52 | irq_ptr->qib.pfmt = qib_param_field_format; | 51 | irq_ptr->qib.pfmt = qib_param_field_format; |
53 | if (qib_param_field) | 52 | if (qib_param_field) |
54 | memcpy(irq_ptr->qib.parm, qib_param_field, | 53 | memcpy(irq_ptr->qib.parm, qib_param_field, |
@@ -82,14 +81,12 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues) | |||
82 | q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); | 81 | q = kmem_cache_alloc(qdio_q_cache, GFP_KERNEL); |
83 | if (!q) | 82 | if (!q) |
84 | return -ENOMEM; | 83 | return -ENOMEM; |
85 | WARN_ON((unsigned long)q & 0xff); | ||
86 | 84 | ||
87 | q->slib = (struct slib *) __get_free_page(GFP_KERNEL); | 85 | q->slib = (struct slib *) __get_free_page(GFP_KERNEL); |
88 | if (!q->slib) { | 86 | if (!q->slib) { |
89 | kmem_cache_free(qdio_q_cache, q); | 87 | kmem_cache_free(qdio_q_cache, q); |
90 | return -ENOMEM; | 88 | return -ENOMEM; |
91 | } | 89 | } |
92 | WARN_ON((unsigned long)q->slib & 0x7ff); | ||
93 | irq_ptr_qs[i] = q; | 90 | irq_ptr_qs[i] = q; |
94 | } | 91 | } |
95 | return 0; | 92 | return 0; |
@@ -131,7 +128,7 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, | |||
131 | /* fill in sbal */ | 128 | /* fill in sbal */ |
132 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) { | 129 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) { |
133 | q->sbal[j] = *sbals_array++; | 130 | q->sbal[j] = *sbals_array++; |
134 | WARN_ON((unsigned long)q->sbal[j] & 0xff); | 131 | BUG_ON((unsigned long)q->sbal[j] & 0xff); |
135 | } | 132 | } |
136 | 133 | ||
137 | /* fill in slib */ | 134 | /* fill in slib */ |
@@ -147,11 +144,6 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr, | |||
147 | /* fill in sl */ | 144 | /* fill in sl */ |
148 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) | 145 | for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) |
149 | q->sl->element[j].sbal = (unsigned long)q->sbal[j]; | 146 | q->sl->element[j].sbal = (unsigned long)q->sbal[j]; |
150 | |||
151 | DBF_EVENT("sl-slsb-sbal"); | ||
152 | DBF_HEX(q->sl, sizeof(void *)); | ||
153 | DBF_HEX(&q->slsb, sizeof(void *)); | ||
154 | DBF_HEX(q->sbal, sizeof(void *)); | ||
155 | } | 147 | } |
156 | 148 | ||
157 | static void setup_queues(struct qdio_irq *irq_ptr, | 149 | static void setup_queues(struct qdio_irq *irq_ptr, |
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c index 981a77ea7ee2..091d904d3182 100644 --- a/drivers/s390/cio/qdio_thinint.c +++ b/drivers/s390/cio/qdio_thinint.c | |||
@@ -1,9 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/drivers/s390/cio/thinint_qdio.c | 2 | * linux/drivers/s390/cio/thinint_qdio.c |
3 | * | 3 | * |
4 | * thin interrupt support for qdio | 4 | * Copyright 2000,2009 IBM Corp. |
5 | * | ||
6 | * Copyright 2000-2008 IBM Corp. | ||
7 | * Author(s): Utz Bacher <utz.bacher@de.ibm.com> | 5 | * Author(s): Utz Bacher <utz.bacher@de.ibm.com> |
8 | * Cornelia Huck <cornelia.huck@de.ibm.com> | 6 | * Cornelia Huck <cornelia.huck@de.ibm.com> |
9 | * Jan Glauber <jang@linux.vnet.ibm.com> | 7 | * Jan Glauber <jang@linux.vnet.ibm.com> |
@@ -19,7 +17,6 @@ | |||
19 | #include "ioasm.h" | 17 | #include "ioasm.h" |
20 | #include "qdio.h" | 18 | #include "qdio.h" |
21 | #include "qdio_debug.h" | 19 | #include "qdio_debug.h" |
22 | #include "qdio_perf.h" | ||
23 | 20 | ||
24 | /* | 21 | /* |
25 | * Restriction: only 63 iqdio subchannels would have its own indicator, | 22 | * Restriction: only 63 iqdio subchannels would have its own indicator, |
@@ -132,8 +129,6 @@ static void tiqdio_thinint_handler(void *ind, void *drv_data) | |||
132 | { | 129 | { |
133 | struct qdio_q *q; | 130 | struct qdio_q *q; |
134 | 131 | ||
135 | qdio_perf_stat_inc(&perf_stats.thin_int); | ||
136 | |||
137 | /* | 132 | /* |
138 | * SVS only when needed: issue SVS to benefit from iqdio interrupt | 133 | * SVS only when needed: issue SVS to benefit from iqdio interrupt |
139 | * avoidance (SVS clears adapter interrupt suppression overwrite) | 134 | * avoidance (SVS clears adapter interrupt suppression overwrite) |
@@ -154,6 +149,7 @@ static void tiqdio_thinint_handler(void *ind, void *drv_data) | |||
154 | list_for_each_entry_rcu(q, &tiq_list, entry) | 149 | list_for_each_entry_rcu(q, &tiq_list, entry) |
155 | /* only process queues from changed sets */ | 150 | /* only process queues from changed sets */ |
156 | if (*q->irq_ptr->dsci) { | 151 | if (*q->irq_ptr->dsci) { |
152 | qperf_inc(q, adapter_int); | ||
157 | 153 | ||
158 | /* only clear it if the indicator is non-shared */ | 154 | /* only clear it if the indicator is non-shared */ |
159 | if (!shared_ind(q->irq_ptr)) | 155 | if (!shared_ind(q->irq_ptr)) |
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c index 395c04c2b00f..65ebee0a3266 100644 --- a/drivers/s390/net/netiucv.c +++ b/drivers/s390/net/netiucv.c | |||
@@ -113,11 +113,9 @@ static inline int iucv_dbf_passes(debug_info_t *dbf_grp, int level) | |||
113 | #define IUCV_DBF_TEXT_(name, level, text...) \ | 113 | #define IUCV_DBF_TEXT_(name, level, text...) \ |
114 | do { \ | 114 | do { \ |
115 | if (iucv_dbf_passes(iucv_dbf_##name, level)) { \ | 115 | if (iucv_dbf_passes(iucv_dbf_##name, level)) { \ |
116 | char* iucv_dbf_txt_buf = \ | 116 | char* __buf = get_cpu_var(iucv_dbf_txt_buf); \ |
117 | get_cpu_var(iucv_dbf_txt_buf); \ | 117 | sprintf(__buf, text); \ |
118 | sprintf(iucv_dbf_txt_buf, text); \ | 118 | debug_text_event(iucv_dbf_##name, level, __buf); \ |
119 | debug_text_event(iucv_dbf_##name, level, \ | ||
120 | iucv_dbf_txt_buf); \ | ||
121 | put_cpu_var(iucv_dbf_txt_buf); \ | 119 | put_cpu_var(iucv_dbf_txt_buf); \ |
122 | } \ | 120 | } \ |
123 | } while (0) | 121 | } while (0) |
@@ -161,7 +159,7 @@ static void netiucv_pm_complete(struct device *); | |||
161 | static int netiucv_pm_freeze(struct device *); | 159 | static int netiucv_pm_freeze(struct device *); |
162 | static int netiucv_pm_restore_thaw(struct device *); | 160 | static int netiucv_pm_restore_thaw(struct device *); |
163 | 161 | ||
164 | static struct dev_pm_ops netiucv_pm_ops = { | 162 | static const struct dev_pm_ops netiucv_pm_ops = { |
165 | .prepare = netiucv_pm_prepare, | 163 | .prepare = netiucv_pm_prepare, |
166 | .complete = netiucv_pm_complete, | 164 | .complete = netiucv_pm_complete, |
167 | .freeze = netiucv_pm_freeze, | 165 | .freeze = netiucv_pm_freeze, |
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c index 3012355f8304..67f2485d2372 100644 --- a/drivers/s390/net/smsgiucv.c +++ b/drivers/s390/net/smsgiucv.c | |||
@@ -168,7 +168,7 @@ static int smsg_pm_restore_thaw(struct device *dev) | |||
168 | return 0; | 168 | return 0; |
169 | } | 169 | } |
170 | 170 | ||
171 | static struct dev_pm_ops smsg_pm_ops = { | 171 | static const struct dev_pm_ops smsg_pm_ops = { |
172 | .freeze = smsg_pm_freeze, | 172 | .freeze = smsg_pm_freeze, |
173 | .thaw = smsg_pm_restore_thaw, | 173 | .thaw = smsg_pm_restore_thaw, |
174 | .restore = smsg_pm_restore_thaw, | 174 | .restore = smsg_pm_restore_thaw, |