diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 20:42:32 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 20:42:32 -0500 |
commit | b3d6524ff7956c5a898d51a18eaecb62a60a2b84 (patch) | |
tree | cc049e7ec9edd9f5a76f286e04d8db9a1caa516a /drivers/s390 | |
parent | 07f80d41cf24b7e6e76cd97d420167932c9a7f82 (diff) | |
parent | 6a039eab53c01a58bfff95c78fc800ca7de27c77 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky:
- The remaining patches for the z13 machine support: kernel build
option for z13, the cache synonym avoidance, SMT support,
compare-and-delay for spinloops and the CES5S crypto adapater.
- The ftrace support for function tracing with the gcc hotpatch option.
This touches common code Makefiles, Steven is ok with the changes.
- The hypfs file system gets an extension to access diagnose 0x0c data
in user space for performance analysis for Linux running under z/VM.
- The iucv hvc console gets wildcard spport for the user id filtering.
- The cacheinfo code is converted to use the generic infrastructure.
- Cleanup and bug fixes.
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (42 commits)
s390/process: free vx save area when releasing tasks
s390/hypfs: Eliminate hypfs interval
s390/hypfs: Add diagnose 0c support
s390/cacheinfo: don't use smp_processor_id() in preemptible context
s390/zcrypt: fixed domain scanning problem (again)
s390/smp: increase maximum value of NR_CPUS to 512
s390/jump label: use different nop instruction
s390/jump label: add sanity checks
s390/mm: correct missing space when reporting user process faults
s390/dasd: cleanup profiling
s390/dasd: add locking for global_profile access
s390/ftrace: hotpatch support for function tracing
ftrace: let notrace function attribute disable hotpatching if necessary
ftrace: allow architectures to specify ftrace compile options
s390: reintroduce diag 44 calls for cpu_relax()
s390/zcrypt: Add support for new crypto express (CEX5S) adapter.
s390/zcrypt: Number of supported ap domains is not retrievable.
s390/spinlock: add compare-and-delay to lock wait loops
s390/tape: remove redundant if statement
s390/hvc_iucv: add simple wildcard matches to the iucv allow filter
...
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd.c | 102 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 3 | ||||
-rw-r--r-- | drivers/s390/block/dasd_proc.c | 21 | ||||
-rw-r--r-- | drivers/s390/block/dcssblk.c | 15 | ||||
-rw-r--r-- | drivers/s390/char/hmcdrv_ftp.c | 6 | ||||
-rw-r--r-- | drivers/s390/char/hmcdrv_mod.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/sclp_early.c | 49 | ||||
-rw-r--r-- | drivers/s390/char/tape_34xx.c | 12 | ||||
-rw-r--r-- | drivers/s390/cio/cio.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/idset.c | 20 | ||||
-rw-r--r-- | drivers/s390/cio/idset.h | 2 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.c | 144 | ||||
-rw-r--r-- | drivers/s390/crypto/ap_bus.h | 1 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_api.h | 1 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_cex4.c | 33 |
15 files changed, 229 insertions, 183 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 4abf11965484..be34ef41b7c7 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -674,8 +674,9 @@ EXPORT_SYMBOL(dasd_enable_device); | |||
674 | unsigned int dasd_global_profile_level = DASD_PROFILE_OFF; | 674 | unsigned int dasd_global_profile_level = DASD_PROFILE_OFF; |
675 | 675 | ||
676 | #ifdef CONFIG_DASD_PROFILE | 676 | #ifdef CONFIG_DASD_PROFILE |
677 | struct dasd_profile_info dasd_global_profile_data; | 677 | struct dasd_profile dasd_global_profile = { |
678 | static struct dentry *dasd_global_profile_dentry; | 678 | .lock = __SPIN_LOCK_UNLOCKED(dasd_global_profile.lock), |
679 | }; | ||
679 | static struct dentry *dasd_debugfs_global_entry; | 680 | static struct dentry *dasd_debugfs_global_entry; |
680 | 681 | ||
681 | /* | 682 | /* |
@@ -696,11 +697,13 @@ static void dasd_profile_start(struct dasd_block *block, | |||
696 | if (++counter >= 31) | 697 | if (++counter >= 31) |
697 | break; | 698 | break; |
698 | 699 | ||
699 | if (dasd_global_profile_level) { | 700 | spin_lock(&dasd_global_profile.lock); |
700 | dasd_global_profile_data.dasd_io_nr_req[counter]++; | 701 | if (dasd_global_profile.data) { |
702 | dasd_global_profile.data->dasd_io_nr_req[counter]++; | ||
701 | if (rq_data_dir(req) == READ) | 703 | if (rq_data_dir(req) == READ) |
702 | dasd_global_profile_data.dasd_read_nr_req[counter]++; | 704 | dasd_global_profile.data->dasd_read_nr_req[counter]++; |
703 | } | 705 | } |
706 | spin_unlock(&dasd_global_profile.lock); | ||
704 | 707 | ||
705 | spin_lock(&block->profile.lock); | 708 | spin_lock(&block->profile.lock); |
706 | if (block->profile.data) { | 709 | if (block->profile.data) { |
@@ -825,8 +828,9 @@ static void dasd_profile_end(struct dasd_block *block, | |||
825 | dasd_profile_counter(irqtime / sectors, irqtimeps_ind); | 828 | dasd_profile_counter(irqtime / sectors, irqtimeps_ind); |
826 | dasd_profile_counter(endtime, endtime_ind); | 829 | dasd_profile_counter(endtime, endtime_ind); |
827 | 830 | ||
828 | if (dasd_global_profile_level) { | 831 | spin_lock(&dasd_global_profile.lock); |
829 | dasd_profile_end_add_data(&dasd_global_profile_data, | 832 | if (dasd_global_profile.data) { |
833 | dasd_profile_end_add_data(dasd_global_profile.data, | ||
830 | cqr->startdev != block->base, | 834 | cqr->startdev != block->base, |
831 | cqr->cpmode == 1, | 835 | cqr->cpmode == 1, |
832 | rq_data_dir(req) == READ, | 836 | rq_data_dir(req) == READ, |
@@ -835,6 +839,7 @@ static void dasd_profile_end(struct dasd_block *block, | |||
835 | irqtime_ind, irqtimeps_ind, | 839 | irqtime_ind, irqtimeps_ind, |
836 | endtime_ind); | 840 | endtime_ind); |
837 | } | 841 | } |
842 | spin_unlock(&dasd_global_profile.lock); | ||
838 | 843 | ||
839 | spin_lock(&block->profile.lock); | 844 | spin_lock(&block->profile.lock); |
840 | if (block->profile.data) | 845 | if (block->profile.data) |
@@ -876,12 +881,6 @@ void dasd_profile_reset(struct dasd_profile *profile) | |||
876 | spin_unlock_bh(&profile->lock); | 881 | spin_unlock_bh(&profile->lock); |
877 | } | 882 | } |
878 | 883 | ||
879 | void dasd_global_profile_reset(void) | ||
880 | { | ||
881 | memset(&dasd_global_profile_data, 0, sizeof(dasd_global_profile_data)); | ||
882 | getnstimeofday(&dasd_global_profile_data.starttod); | ||
883 | } | ||
884 | |||
885 | int dasd_profile_on(struct dasd_profile *profile) | 884 | int dasd_profile_on(struct dasd_profile *profile) |
886 | { | 885 | { |
887 | struct dasd_profile_info *data; | 886 | struct dasd_profile_info *data; |
@@ -949,12 +948,20 @@ static ssize_t dasd_stats_write(struct file *file, | |||
949 | dasd_profile_reset(prof); | 948 | dasd_profile_reset(prof); |
950 | } else if (strncmp(str, "on", 2) == 0) { | 949 | } else if (strncmp(str, "on", 2) == 0) { |
951 | rc = dasd_profile_on(prof); | 950 | rc = dasd_profile_on(prof); |
952 | if (!rc) | 951 | if (rc) |
953 | rc = user_len; | 952 | goto out; |
953 | rc = user_len; | ||
954 | if (prof == &dasd_global_profile) { | ||
955 | dasd_profile_reset(prof); | ||
956 | dasd_global_profile_level = DASD_PROFILE_GLOBAL_ONLY; | ||
957 | } | ||
954 | } else if (strncmp(str, "off", 3) == 0) { | 958 | } else if (strncmp(str, "off", 3) == 0) { |
959 | if (prof == &dasd_global_profile) | ||
960 | dasd_global_profile_level = DASD_PROFILE_OFF; | ||
955 | dasd_profile_off(prof); | 961 | dasd_profile_off(prof); |
956 | } else | 962 | } else |
957 | rc = -EINVAL; | 963 | rc = -EINVAL; |
964 | out: | ||
958 | vfree(buffer); | 965 | vfree(buffer); |
959 | return rc; | 966 | return rc; |
960 | } | 967 | } |
@@ -1044,57 +1051,6 @@ static const struct file_operations dasd_stats_raw_fops = { | |||
1044 | .write = dasd_stats_write, | 1051 | .write = dasd_stats_write, |
1045 | }; | 1052 | }; |
1046 | 1053 | ||
1047 | static ssize_t dasd_stats_global_write(struct file *file, | ||
1048 | const char __user *user_buf, | ||
1049 | size_t user_len, loff_t *pos) | ||
1050 | { | ||
1051 | char *buffer, *str; | ||
1052 | ssize_t rc; | ||
1053 | |||
1054 | if (user_len > 65536) | ||
1055 | user_len = 65536; | ||
1056 | buffer = dasd_get_user_string(user_buf, user_len); | ||
1057 | if (IS_ERR(buffer)) | ||
1058 | return PTR_ERR(buffer); | ||
1059 | str = skip_spaces(buffer); | ||
1060 | rc = user_len; | ||
1061 | if (strncmp(str, "reset", 5) == 0) { | ||
1062 | dasd_global_profile_reset(); | ||
1063 | } else if (strncmp(str, "on", 2) == 0) { | ||
1064 | dasd_global_profile_reset(); | ||
1065 | dasd_global_profile_level = DASD_PROFILE_GLOBAL_ONLY; | ||
1066 | } else if (strncmp(str, "off", 3) == 0) { | ||
1067 | dasd_global_profile_level = DASD_PROFILE_OFF; | ||
1068 | } else | ||
1069 | rc = -EINVAL; | ||
1070 | vfree(buffer); | ||
1071 | return rc; | ||
1072 | } | ||
1073 | |||
1074 | static int dasd_stats_global_show(struct seq_file *m, void *v) | ||
1075 | { | ||
1076 | if (!dasd_global_profile_level) { | ||
1077 | seq_puts(m, "disabled\n"); | ||
1078 | return 0; | ||
1079 | } | ||
1080 | dasd_stats_seq_print(m, &dasd_global_profile_data); | ||
1081 | return 0; | ||
1082 | } | ||
1083 | |||
1084 | static int dasd_stats_global_open(struct inode *inode, struct file *file) | ||
1085 | { | ||
1086 | return single_open(file, dasd_stats_global_show, NULL); | ||
1087 | } | ||
1088 | |||
1089 | static const struct file_operations dasd_stats_global_fops = { | ||
1090 | .owner = THIS_MODULE, | ||
1091 | .open = dasd_stats_global_open, | ||
1092 | .read = seq_read, | ||
1093 | .llseek = seq_lseek, | ||
1094 | .release = single_release, | ||
1095 | .write = dasd_stats_global_write, | ||
1096 | }; | ||
1097 | |||
1098 | static void dasd_profile_init(struct dasd_profile *profile, | 1054 | static void dasd_profile_init(struct dasd_profile *profile, |
1099 | struct dentry *base_dentry) | 1055 | struct dentry *base_dentry) |
1100 | { | 1056 | { |
@@ -1123,20 +1079,16 @@ static void dasd_profile_exit(struct dasd_profile *profile) | |||
1123 | static void dasd_statistics_removeroot(void) | 1079 | static void dasd_statistics_removeroot(void) |
1124 | { | 1080 | { |
1125 | dasd_global_profile_level = DASD_PROFILE_OFF; | 1081 | dasd_global_profile_level = DASD_PROFILE_OFF; |
1126 | debugfs_remove(dasd_global_profile_dentry); | 1082 | dasd_profile_exit(&dasd_global_profile); |
1127 | dasd_global_profile_dentry = NULL; | ||
1128 | debugfs_remove(dasd_debugfs_global_entry); | 1083 | debugfs_remove(dasd_debugfs_global_entry); |
1129 | debugfs_remove(dasd_debugfs_root_entry); | 1084 | debugfs_remove(dasd_debugfs_root_entry); |
1130 | } | 1085 | } |
1131 | 1086 | ||
1132 | static void dasd_statistics_createroot(void) | 1087 | static void dasd_statistics_createroot(void) |
1133 | { | 1088 | { |
1134 | umode_t mode; | ||
1135 | struct dentry *pde; | 1089 | struct dentry *pde; |
1136 | 1090 | ||
1137 | dasd_debugfs_root_entry = NULL; | 1091 | dasd_debugfs_root_entry = NULL; |
1138 | dasd_debugfs_global_entry = NULL; | ||
1139 | dasd_global_profile_dentry = NULL; | ||
1140 | pde = debugfs_create_dir("dasd", NULL); | 1092 | pde = debugfs_create_dir("dasd", NULL); |
1141 | if (!pde || IS_ERR(pde)) | 1093 | if (!pde || IS_ERR(pde)) |
1142 | goto error; | 1094 | goto error; |
@@ -1145,13 +1097,7 @@ static void dasd_statistics_createroot(void) | |||
1145 | if (!pde || IS_ERR(pde)) | 1097 | if (!pde || IS_ERR(pde)) |
1146 | goto error; | 1098 | goto error; |
1147 | dasd_debugfs_global_entry = pde; | 1099 | dasd_debugfs_global_entry = pde; |
1148 | 1100 | dasd_profile_init(&dasd_global_profile, dasd_debugfs_global_entry); | |
1149 | mode = (S_IRUSR | S_IWUSR | S_IFREG); | ||
1150 | pde = debugfs_create_file("statistics", mode, dasd_debugfs_global_entry, | ||
1151 | NULL, &dasd_stats_global_fops); | ||
1152 | if (!pde || IS_ERR(pde)) | ||
1153 | goto error; | ||
1154 | dasd_global_profile_dentry = pde; | ||
1155 | return; | 1101 | return; |
1156 | 1102 | ||
1157 | error: | 1103 | error: |
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h index 8b5d4100abf7..227e3dea3155 100644 --- a/drivers/s390/block/dasd_int.h +++ b/drivers/s390/block/dasd_int.h | |||
@@ -651,7 +651,7 @@ dasd_check_blocksize(int bsize) | |||
651 | #define DASD_PROFILE_GLOBAL_ONLY 2 | 651 | #define DASD_PROFILE_GLOBAL_ONLY 2 |
652 | 652 | ||
653 | extern debug_info_t *dasd_debug_area; | 653 | extern debug_info_t *dasd_debug_area; |
654 | extern struct dasd_profile_info dasd_global_profile_data; | 654 | extern struct dasd_profile dasd_global_profile; |
655 | extern unsigned int dasd_global_profile_level; | 655 | extern unsigned int dasd_global_profile_level; |
656 | extern const struct block_device_operations dasd_device_operations; | 656 | extern const struct block_device_operations dasd_device_operations; |
657 | 657 | ||
@@ -728,7 +728,6 @@ int dasd_device_is_ro(struct dasd_device *); | |||
728 | void dasd_profile_reset(struct dasd_profile *); | 728 | void dasd_profile_reset(struct dasd_profile *); |
729 | int dasd_profile_on(struct dasd_profile *); | 729 | int dasd_profile_on(struct dasd_profile *); |
730 | void dasd_profile_off(struct dasd_profile *); | 730 | void dasd_profile_off(struct dasd_profile *); |
731 | void dasd_global_profile_reset(void); | ||
732 | char *dasd_get_user_string(const char __user *, size_t); | 731 | char *dasd_get_user_string(const char __user *, size_t); |
733 | 732 | ||
734 | /* externals in dasd_devmap.c */ | 733 | /* externals in dasd_devmap.c */ |
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c index 78ac905a5b7f..aa7bb2d1da81 100644 --- a/drivers/s390/block/dasd_proc.c +++ b/drivers/s390/block/dasd_proc.c | |||
@@ -212,14 +212,15 @@ static int dasd_stats_proc_show(struct seq_file *m, void *v) | |||
212 | struct dasd_profile_info *prof; | 212 | struct dasd_profile_info *prof; |
213 | int factor; | 213 | int factor; |
214 | 214 | ||
215 | /* check for active profiling */ | 215 | spin_lock_bh(&dasd_global_profile.lock); |
216 | if (!dasd_global_profile_level) { | 216 | prof = dasd_global_profile.data; |
217 | if (!prof) { | ||
218 | spin_unlock_bh(&dasd_global_profile.lock); | ||
217 | seq_printf(m, "Statistics are off - they might be " | 219 | seq_printf(m, "Statistics are off - they might be " |
218 | "switched on using 'echo set on > " | 220 | "switched on using 'echo set on > " |
219 | "/proc/dasd/statistics'\n"); | 221 | "/proc/dasd/statistics'\n"); |
220 | return 0; | 222 | return 0; |
221 | } | 223 | } |
222 | prof = &dasd_global_profile_data; | ||
223 | 224 | ||
224 | /* prevent counter 'overflow' on output */ | 225 | /* prevent counter 'overflow' on output */ |
225 | for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999; | 226 | for (factor = 1; (prof->dasd_io_reqs / factor) > 9999999; |
@@ -255,6 +256,7 @@ static int dasd_stats_proc_show(struct seq_file *m, void *v) | |||
255 | dasd_statistics_array(m, prof->dasd_io_time3, factor); | 256 | dasd_statistics_array(m, prof->dasd_io_time3, factor); |
256 | seq_printf(m, "# of req in chanq at enqueuing (1..32) \n"); | 257 | seq_printf(m, "# of req in chanq at enqueuing (1..32) \n"); |
257 | dasd_statistics_array(m, prof->dasd_io_nr_req, factor); | 258 | dasd_statistics_array(m, prof->dasd_io_nr_req, factor); |
259 | spin_unlock_bh(&dasd_global_profile.lock); | ||
258 | #else | 260 | #else |
259 | seq_printf(m, "Statistics are not activated in this kernel\n"); | 261 | seq_printf(m, "Statistics are not activated in this kernel\n"); |
260 | #endif | 262 | #endif |
@@ -291,14 +293,19 @@ static ssize_t dasd_stats_proc_write(struct file *file, | |||
291 | dasd_stats_all_block_off(); | 293 | dasd_stats_all_block_off(); |
292 | goto out_error; | 294 | goto out_error; |
293 | } | 295 | } |
294 | dasd_global_profile_reset(); | 296 | rc = dasd_profile_on(&dasd_global_profile); |
297 | if (rc) { | ||
298 | dasd_stats_all_block_off(); | ||
299 | goto out_error; | ||
300 | } | ||
301 | dasd_profile_reset(&dasd_global_profile); | ||
295 | dasd_global_profile_level = DASD_PROFILE_ON; | 302 | dasd_global_profile_level = DASD_PROFILE_ON; |
296 | pr_info("The statistics feature has been switched " | 303 | pr_info("The statistics feature has been switched " |
297 | "on\n"); | 304 | "on\n"); |
298 | } else if (strcmp(str, "off") == 0) { | 305 | } else if (strcmp(str, "off") == 0) { |
299 | /* switch off and reset statistics profiling */ | 306 | /* switch off statistics profiling */ |
300 | dasd_global_profile_level = DASD_PROFILE_OFF; | 307 | dasd_global_profile_level = DASD_PROFILE_OFF; |
301 | dasd_global_profile_reset(); | 308 | dasd_profile_off(&dasd_global_profile); |
302 | dasd_stats_all_block_off(); | 309 | dasd_stats_all_block_off(); |
303 | pr_info("The statistics feature has been switched " | 310 | pr_info("The statistics feature has been switched " |
304 | "off\n"); | 311 | "off\n"); |
@@ -306,7 +313,7 @@ static ssize_t dasd_stats_proc_write(struct file *file, | |||
306 | goto out_parse_error; | 313 | goto out_parse_error; |
307 | } else if (strncmp(str, "reset", 5) == 0) { | 314 | } else if (strncmp(str, "reset", 5) == 0) { |
308 | /* reset the statistics */ | 315 | /* reset the statistics */ |
309 | dasd_global_profile_reset(); | 316 | dasd_profile_reset(&dasd_global_profile); |
310 | dasd_stats_all_block_reset(); | 317 | dasd_stats_all_block_reset(); |
311 | pr_info("The statistics have been reset\n"); | 318 | pr_info("The statistics have been reset\n"); |
312 | } else | 319 | } else |
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index b550c8c8d010..7f900229404d 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c | |||
@@ -438,7 +438,13 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char | |||
438 | pr_info("All DCSSs that map to device %s are " | 438 | pr_info("All DCSSs that map to device %s are " |
439 | "saved\n", dev_info->segment_name); | 439 | "saved\n", dev_info->segment_name); |
440 | list_for_each_entry(entry, &dev_info->seg_list, lh) { | 440 | list_for_each_entry(entry, &dev_info->seg_list, lh) { |
441 | segment_save(entry->segment_name); | 441 | if (entry->segment_type == SEG_TYPE_EN || |
442 | entry->segment_type == SEG_TYPE_SN) | ||
443 | pr_warn("DCSS %s is of type SN or EN" | ||
444 | " and cannot be saved\n", | ||
445 | entry->segment_name); | ||
446 | else | ||
447 | segment_save(entry->segment_name); | ||
442 | } | 448 | } |
443 | } else { | 449 | } else { |
444 | // device is busy => we save it when it becomes | 450 | // device is busy => we save it when it becomes |
@@ -797,7 +803,12 @@ dcssblk_release(struct gendisk *disk, fmode_t mode) | |||
797 | pr_info("Device %s has become idle and is being saved " | 803 | pr_info("Device %s has become idle and is being saved " |
798 | "now\n", dev_info->segment_name); | 804 | "now\n", dev_info->segment_name); |
799 | list_for_each_entry(entry, &dev_info->seg_list, lh) { | 805 | list_for_each_entry(entry, &dev_info->seg_list, lh) { |
800 | segment_save(entry->segment_name); | 806 | if (entry->segment_type == SEG_TYPE_EN || |
807 | entry->segment_type == SEG_TYPE_SN) | ||
808 | pr_warn("DCSS %s is of type SN or EN and cannot" | ||
809 | " be saved\n", entry->segment_name); | ||
810 | else | ||
811 | segment_save(entry->segment_name); | ||
801 | } | 812 | } |
802 | dev_info->save_pending = 0; | 813 | dev_info->save_pending = 0; |
803 | } | 814 | } |
diff --git a/drivers/s390/char/hmcdrv_ftp.c b/drivers/s390/char/hmcdrv_ftp.c index 4bd63322fc29..d4b61d9088fb 100644 --- a/drivers/s390/char/hmcdrv_ftp.c +++ b/drivers/s390/char/hmcdrv_ftp.c | |||
@@ -200,10 +200,9 @@ int hmcdrv_ftp_probe(void) | |||
200 | rc = hmcdrv_ftp_startup(); | 200 | rc = hmcdrv_ftp_startup(); |
201 | 201 | ||
202 | if (rc) | 202 | if (rc) |
203 | return rc; | 203 | goto out; |
204 | 204 | ||
205 | rc = hmcdrv_ftp_do(&ftp); | 205 | rc = hmcdrv_ftp_do(&ftp); |
206 | free_page((unsigned long) ftp.buf); | ||
207 | hmcdrv_ftp_shutdown(); | 206 | hmcdrv_ftp_shutdown(); |
208 | 207 | ||
209 | switch (rc) { | 208 | switch (rc) { |
@@ -216,7 +215,8 @@ int hmcdrv_ftp_probe(void) | |||
216 | rc = 0; /* clear length (success) */ | 215 | rc = 0; /* clear length (success) */ |
217 | break; | 216 | break; |
218 | } /* switch */ | 217 | } /* switch */ |
219 | 218 | out: | |
219 | free_page((unsigned long) ftp.buf); | ||
220 | return rc; | 220 | return rc; |
221 | } | 221 | } |
222 | EXPORT_SYMBOL(hmcdrv_ftp_probe); | 222 | EXPORT_SYMBOL(hmcdrv_ftp_probe); |
diff --git a/drivers/s390/char/hmcdrv_mod.c b/drivers/s390/char/hmcdrv_mod.c index 505c6a78ee1a..251a318a9b75 100644 --- a/drivers/s390/char/hmcdrv_mod.c +++ b/drivers/s390/char/hmcdrv_mod.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/moduleparam.h> | 13 | #include <linux/moduleparam.h> |
14 | #include <linux/version.h> | ||
15 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
16 | 15 | ||
17 | #include "hmcdrv_ftp.h" | 16 | #include "hmcdrv_ftp.h" |
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c index 5bd6cb145a87..daf6cd5079ec 100644 --- a/drivers/s390/char/sclp_early.c +++ b/drivers/s390/char/sclp_early.c | |||
@@ -20,26 +20,31 @@ struct read_info_sccb { | |||
20 | struct sccb_header header; /* 0-7 */ | 20 | struct sccb_header header; /* 0-7 */ |
21 | u16 rnmax; /* 8-9 */ | 21 | u16 rnmax; /* 8-9 */ |
22 | u8 rnsize; /* 10 */ | 22 | u8 rnsize; /* 10 */ |
23 | u8 _reserved0[16 - 11]; /* 11-15 */ | 23 | u8 _pad_11[16 - 11]; /* 11-15 */ |
24 | u16 ncpurl; /* 16-17 */ | 24 | u16 ncpurl; /* 16-17 */ |
25 | u16 cpuoff; /* 18-19 */ | 25 | u16 cpuoff; /* 18-19 */ |
26 | u8 _reserved7[24 - 20]; /* 20-23 */ | 26 | u8 _pad_20[24 - 20]; /* 20-23 */ |
27 | u8 loadparm[8]; /* 24-31 */ | 27 | u8 loadparm[8]; /* 24-31 */ |
28 | u8 _reserved1[48 - 32]; /* 32-47 */ | 28 | u8 _pad_32[42 - 32]; /* 32-41 */ |
29 | u8 fac42; /* 42 */ | ||
30 | u8 fac43; /* 43 */ | ||
31 | u8 _pad_44[48 - 44]; /* 44-47 */ | ||
29 | u64 facilities; /* 48-55 */ | 32 | u64 facilities; /* 48-55 */ |
30 | u8 _reserved2a[76 - 56]; /* 56-75 */ | 33 | u8 _pad_56[66 - 56]; /* 56-65 */ |
34 | u8 fac66; /* 66 */ | ||
35 | u8 _pad_67[76 - 67]; /* 67-83 */ | ||
31 | u32 ibc; /* 76-79 */ | 36 | u32 ibc; /* 76-79 */ |
32 | u8 _reserved2b[84 - 80]; /* 80-83 */ | 37 | u8 _pad80[84 - 80]; /* 80-83 */ |
33 | u8 fac84; /* 84 */ | 38 | u8 fac84; /* 84 */ |
34 | u8 fac85; /* 85 */ | 39 | u8 fac85; /* 85 */ |
35 | u8 _reserved3[91 - 86]; /* 86-90 */ | 40 | u8 _pad_86[91 - 86]; /* 86-90 */ |
36 | u8 flags; /* 91 */ | 41 | u8 flags; /* 91 */ |
37 | u8 _reserved4[100 - 92]; /* 92-99 */ | 42 | u8 _pad_92[100 - 92]; /* 92-99 */ |
38 | u32 rnsize2; /* 100-103 */ | 43 | u32 rnsize2; /* 100-103 */ |
39 | u64 rnmax2; /* 104-111 */ | 44 | u64 rnmax2; /* 104-111 */ |
40 | u8 _reserved5[120 - 112]; /* 112-119 */ | 45 | u8 _pad_112[120 - 112]; /* 112-119 */ |
41 | u16 hcpua; /* 120-121 */ | 46 | u16 hcpua; /* 120-121 */ |
42 | u8 _reserved6[4096 - 122]; /* 122-4095 */ | 47 | u8 _pad_122[4096 - 122]; /* 122-4095 */ |
43 | } __packed __aligned(PAGE_SIZE); | 48 | } __packed __aligned(PAGE_SIZE); |
44 | 49 | ||
45 | static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; | 50 | static char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE) __initdata; |
@@ -50,6 +55,10 @@ static unsigned int sclp_max_cpu; | |||
50 | static struct sclp_ipl_info sclp_ipl_info; | 55 | static struct sclp_ipl_info sclp_ipl_info; |
51 | static unsigned char sclp_siif; | 56 | static unsigned char sclp_siif; |
52 | static u32 sclp_ibc; | 57 | static u32 sclp_ibc; |
58 | static unsigned int sclp_mtid; | ||
59 | static unsigned int sclp_mtid_cp; | ||
60 | static unsigned int sclp_mtid_max; | ||
61 | static unsigned int sclp_mtid_prev; | ||
53 | 62 | ||
54 | u64 sclp_facilities; | 63 | u64 sclp_facilities; |
55 | u8 sclp_fac84; | 64 | u8 sclp_fac84; |
@@ -128,7 +137,7 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb) | |||
128 | boot_cpu_address = stap(); | 137 | boot_cpu_address = stap(); |
129 | cpue = (void *)sccb + sccb->cpuoff; | 138 | cpue = (void *)sccb + sccb->cpuoff; |
130 | for (cpu = 0; cpu < sccb->ncpurl; cpue++, cpu++) { | 139 | for (cpu = 0; cpu < sccb->ncpurl; cpue++, cpu++) { |
131 | if (boot_cpu_address != cpue->address) | 140 | if (boot_cpu_address != cpue->core_id) |
132 | continue; | 141 | continue; |
133 | sclp_siif = cpue->siif; | 142 | sclp_siif = cpue->siif; |
134 | break; | 143 | break; |
@@ -139,6 +148,11 @@ static void __init sclp_facilities_detect(struct read_info_sccb *sccb) | |||
139 | if (sccb->flags & 0x2) | 148 | if (sccb->flags & 0x2) |
140 | sclp_ipl_info.has_dump = 1; | 149 | sclp_ipl_info.has_dump = 1; |
141 | memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN); | 150 | memcpy(&sclp_ipl_info.loadparm, &sccb->loadparm, LOADPARM_LEN); |
151 | |||
152 | sclp_mtid = (sccb->fac42 & 0x80) ? (sccb->fac42 & 31) : 0; | ||
153 | sclp_mtid_cp = (sccb->fac42 & 0x80) ? (sccb->fac43 & 31) : 0; | ||
154 | sclp_mtid_max = max(sclp_mtid, sclp_mtid_cp); | ||
155 | sclp_mtid_prev = (sccb->fac42 & 0x80) ? (sccb->fac66 & 31) : 0; | ||
142 | } | 156 | } |
143 | 157 | ||
144 | bool __init sclp_has_linemode(void) | 158 | bool __init sclp_has_linemode(void) |
@@ -178,6 +192,21 @@ unsigned int sclp_get_ibc(void) | |||
178 | } | 192 | } |
179 | EXPORT_SYMBOL(sclp_get_ibc); | 193 | EXPORT_SYMBOL(sclp_get_ibc); |
180 | 194 | ||
195 | unsigned int sclp_get_mtid(u8 cpu_type) | ||
196 | { | ||
197 | return cpu_type ? sclp_mtid : sclp_mtid_cp; | ||
198 | } | ||
199 | |||
200 | unsigned int sclp_get_mtid_max(void) | ||
201 | { | ||
202 | return sclp_mtid_max; | ||
203 | } | ||
204 | |||
205 | unsigned int sclp_get_mtid_prev(void) | ||
206 | { | ||
207 | return sclp_mtid_prev; | ||
208 | } | ||
209 | |||
181 | /* | 210 | /* |
182 | * This function will be called after sclp_facilities_detect(), which gets | 211 | * This function will be called after sclp_facilities_detect(), which gets |
183 | * called from early.c code. The sclp_facilities_detect() function retrieves | 212 | * called from early.c code. The sclp_facilities_detect() function retrieves |
diff --git a/drivers/s390/char/tape_34xx.c b/drivers/s390/char/tape_34xx.c index 9aa79702b370..de69f0ddc321 100644 --- a/drivers/s390/char/tape_34xx.c +++ b/drivers/s390/char/tape_34xx.c | |||
@@ -773,13 +773,11 @@ tape_34xx_unit_check(struct tape_device *device, struct tape_request *request, | |||
773 | "occurred\n"); | 773 | "occurred\n"); |
774 | return tape_34xx_erp_failed(request, -EIO); | 774 | return tape_34xx_erp_failed(request, -EIO); |
775 | case 0x57: | 775 | case 0x57: |
776 | if (device->cdev->id.driver_info == tape_3480) { | 776 | /* |
777 | /* Attention intercept. */ | 777 | * 3480: Attention intercept. |
778 | return tape_34xx_erp_retry(request); | 778 | * 3490: Global status intercept. |
779 | } else { | 779 | */ |
780 | /* Global status intercept. */ | 780 | return tape_34xx_erp_retry(request); |
781 | return tape_34xx_erp_retry(request); | ||
782 | } | ||
783 | case 0x5a: | 781 | case 0x5a: |
784 | /* | 782 | /* |
785 | * Tape length incompatible. The tape inserted is too long, | 783 | * Tape length incompatible. The tape inserted is too long, |
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 10eb738fc81a..3578105989a0 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -938,7 +938,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid) | |||
938 | { | 938 | { |
939 | struct subchannel_id uninitialized_var(schid); | 939 | struct subchannel_id uninitialized_var(schid); |
940 | 940 | ||
941 | s390_reset_system(NULL, NULL); | 941 | s390_reset_system(NULL, NULL, NULL); |
942 | if (reipl_find_schid(devid, &schid) != 0) | 942 | if (reipl_find_schid(devid, &schid) != 0) |
943 | panic("IPL Device not found\n"); | 943 | panic("IPL Device not found\n"); |
944 | do_reipl_asm(*((__u32*)&schid)); | 944 | do_reipl_asm(*((__u32*)&schid)); |
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c index 5a999084a229..b3e06a7b9480 100644 --- a/drivers/s390/cio/idset.c +++ b/drivers/s390/cio/idset.c | |||
@@ -38,11 +38,6 @@ void idset_free(struct idset *set) | |||
38 | vfree(set); | 38 | vfree(set); |
39 | } | 39 | } |
40 | 40 | ||
41 | void idset_clear(struct idset *set) | ||
42 | { | ||
43 | memset(set->bitmap, 0, bitmap_size(set->num_ssid, set->num_id)); | ||
44 | } | ||
45 | |||
46 | void idset_fill(struct idset *set) | 41 | void idset_fill(struct idset *set) |
47 | { | 42 | { |
48 | memset(set->bitmap, 0xff, bitmap_size(set->num_ssid, set->num_id)); | 43 | memset(set->bitmap, 0xff, bitmap_size(set->num_ssid, set->num_id)); |
@@ -103,21 +98,6 @@ int idset_sch_contains(struct idset *set, struct subchannel_id schid) | |||
103 | return idset_contains(set, schid.ssid, schid.sch_no); | 98 | return idset_contains(set, schid.ssid, schid.sch_no); |
104 | } | 99 | } |
105 | 100 | ||
106 | int idset_sch_get_first(struct idset *set, struct subchannel_id *schid) | ||
107 | { | ||
108 | int ssid = 0; | ||
109 | int id = 0; | ||
110 | int rc; | ||
111 | |||
112 | rc = idset_get_first(set, &ssid, &id); | ||
113 | if (rc) { | ||
114 | init_subchannel_id(schid); | ||
115 | schid->ssid = ssid; | ||
116 | schid->sch_no = id; | ||
117 | } | ||
118 | return rc; | ||
119 | } | ||
120 | |||
121 | int idset_is_empty(struct idset *set) | 101 | int idset_is_empty(struct idset *set) |
122 | { | 102 | { |
123 | return bitmap_empty(set->bitmap, set->num_ssid * set->num_id); | 103 | return bitmap_empty(set->bitmap, set->num_ssid * set->num_id); |
diff --git a/drivers/s390/cio/idset.h b/drivers/s390/cio/idset.h index 06d3bc01bb09..22b58104683b 100644 --- a/drivers/s390/cio/idset.h +++ b/drivers/s390/cio/idset.h | |||
@@ -11,7 +11,6 @@ | |||
11 | struct idset; | 11 | struct idset; |
12 | 12 | ||
13 | void idset_free(struct idset *set); | 13 | void idset_free(struct idset *set); |
14 | void idset_clear(struct idset *set); | ||
15 | void idset_fill(struct idset *set); | 14 | void idset_fill(struct idset *set); |
16 | 15 | ||
17 | struct idset *idset_sch_new(void); | 16 | struct idset *idset_sch_new(void); |
@@ -19,7 +18,6 @@ void idset_sch_add(struct idset *set, struct subchannel_id id); | |||
19 | void idset_sch_del(struct idset *set, struct subchannel_id id); | 18 | void idset_sch_del(struct idset *set, struct subchannel_id id); |
20 | void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid); | 19 | void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid); |
21 | int idset_sch_contains(struct idset *set, struct subchannel_id id); | 20 | int idset_sch_contains(struct idset *set, struct subchannel_id id); |
22 | int idset_sch_get_first(struct idset *set, struct subchannel_id *id); | ||
23 | int idset_is_empty(struct idset *set); | 21 | int idset_is_empty(struct idset *set); |
24 | void idset_add_set(struct idset *to, struct idset *from); | 22 | void idset_add_set(struct idset *to, struct idset *from); |
25 | 23 | ||
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 4d41bf75c233..3d7f19fb9a4e 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c | |||
@@ -204,6 +204,24 @@ ap_test_queue(ap_qid_t qid, int *queue_depth, int *device_type) | |||
204 | } | 204 | } |
205 | 205 | ||
206 | /** | 206 | /** |
207 | * ap_query_facilities(): PQAP(TAPQ) query facilities. | ||
208 | * @qid: The AP queue number | ||
209 | * | ||
210 | * Returns content of general register 2 after the PQAP(TAPQ) | ||
211 | * instruction was called. | ||
212 | */ | ||
213 | static inline unsigned long ap_query_facilities(ap_qid_t qid) | ||
214 | { | ||
215 | register unsigned long reg0 asm ("0") = qid | 0x00800000UL; | ||
216 | register unsigned long reg1 asm ("1"); | ||
217 | register unsigned long reg2 asm ("2") = 0UL; | ||
218 | |||
219 | asm volatile(".long 0xb2af0000" /* PQAP(TAPQ) */ | ||
220 | : "+d" (reg0), "=d" (reg1), "+d" (reg2) : : "cc"); | ||
221 | return reg2; | ||
222 | } | ||
223 | |||
224 | /** | ||
207 | * ap_reset_queue(): Reset adjunct processor queue. | 225 | * ap_reset_queue(): Reset adjunct processor queue. |
208 | * @qid: The AP queue number | 226 | * @qid: The AP queue number |
209 | * | 227 | * |
@@ -1007,6 +1025,51 @@ void ap_bus_force_rescan(void) | |||
1007 | EXPORT_SYMBOL(ap_bus_force_rescan); | 1025 | EXPORT_SYMBOL(ap_bus_force_rescan); |
1008 | 1026 | ||
1009 | /* | 1027 | /* |
1028 | * ap_test_config(): helper function to extract the nrth bit | ||
1029 | * within the unsigned int array field. | ||
1030 | */ | ||
1031 | static inline int ap_test_config(unsigned int *field, unsigned int nr) | ||
1032 | { | ||
1033 | if (nr > 0xFFu) | ||
1034 | return 0; | ||
1035 | return ap_test_bit((field + (nr >> 5)), (nr & 0x1f)); | ||
1036 | } | ||
1037 | |||
1038 | /* | ||
1039 | * ap_test_config_card_id(): Test, whether an AP card ID is configured. | ||
1040 | * @id AP card ID | ||
1041 | * | ||
1042 | * Returns 0 if the card is not configured | ||
1043 | * 1 if the card is configured or | ||
1044 | * if the configuration information is not available | ||
1045 | */ | ||
1046 | static inline int ap_test_config_card_id(unsigned int id) | ||
1047 | { | ||
1048 | if (!ap_configuration) | ||
1049 | return 1; | ||
1050 | return ap_test_config(ap_configuration->apm, id); | ||
1051 | } | ||
1052 | |||
1053 | /* | ||
1054 | * ap_test_config_domain(): Test, whether an AP usage domain is configured. | ||
1055 | * @domain AP usage domain ID | ||
1056 | * | ||
1057 | * Returns 0 if the usage domain is not configured | ||
1058 | * 1 if the usage domain is configured or | ||
1059 | * if the configuration information is not available | ||
1060 | */ | ||
1061 | static inline int ap_test_config_domain(unsigned int domain) | ||
1062 | { | ||
1063 | if (!ap_configuration) /* QCI not supported */ | ||
1064 | if (domain < 16) | ||
1065 | return 1; /* then domains 0...15 are configured */ | ||
1066 | else | ||
1067 | return 0; | ||
1068 | else | ||
1069 | return ap_test_config(ap_configuration->aqm, domain); | ||
1070 | } | ||
1071 | |||
1072 | /* | ||
1010 | * AP bus attributes. | 1073 | * AP bus attributes. |
1011 | */ | 1074 | */ |
1012 | static ssize_t ap_domain_show(struct bus_type *bus, char *buf) | 1075 | static ssize_t ap_domain_show(struct bus_type *bus, char *buf) |
@@ -1121,6 +1184,42 @@ static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf, | |||
1121 | 1184 | ||
1122 | static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store); | 1185 | static BUS_ATTR(poll_timeout, 0644, poll_timeout_show, poll_timeout_store); |
1123 | 1186 | ||
1187 | static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf) | ||
1188 | { | ||
1189 | ap_qid_t qid; | ||
1190 | int i, nd, max_domain_id = -1; | ||
1191 | unsigned long fbits; | ||
1192 | |||
1193 | if (ap_configuration) { | ||
1194 | if (ap_domain_index >= 0 && ap_domain_index < AP_DOMAINS) { | ||
1195 | for (i = 0; i < AP_DEVICES; i++) { | ||
1196 | if (!ap_test_config_card_id(i)) | ||
1197 | continue; | ||
1198 | qid = AP_MKQID(i, ap_domain_index); | ||
1199 | fbits = ap_query_facilities(qid); | ||
1200 | if (fbits & (1UL << 57)) { | ||
1201 | /* the N bit is 0, Nd field is filled */ | ||
1202 | nd = (int)((fbits & 0x00FF0000UL)>>16); | ||
1203 | if (nd > 0) | ||
1204 | max_domain_id = nd; | ||
1205 | else | ||
1206 | max_domain_id = 15; | ||
1207 | } else { | ||
1208 | /* N bit is 1, max 16 domains */ | ||
1209 | max_domain_id = 15; | ||
1210 | } | ||
1211 | break; | ||
1212 | } | ||
1213 | } | ||
1214 | } else { | ||
1215 | /* no APXA support, older machines with max 16 domains */ | ||
1216 | max_domain_id = 15; | ||
1217 | } | ||
1218 | return snprintf(buf, PAGE_SIZE, "%d\n", max_domain_id); | ||
1219 | } | ||
1220 | |||
1221 | static BUS_ATTR(ap_max_domain_id, 0444, ap_max_domain_id_show, NULL); | ||
1222 | |||
1124 | static struct bus_attribute *const ap_bus_attrs[] = { | 1223 | static struct bus_attribute *const ap_bus_attrs[] = { |
1125 | &bus_attr_ap_domain, | 1224 | &bus_attr_ap_domain, |
1126 | &bus_attr_ap_control_domain_mask, | 1225 | &bus_attr_ap_control_domain_mask, |
@@ -1128,50 +1227,10 @@ static struct bus_attribute *const ap_bus_attrs[] = { | |||
1128 | &bus_attr_poll_thread, | 1227 | &bus_attr_poll_thread, |
1129 | &bus_attr_ap_interrupts, | 1228 | &bus_attr_ap_interrupts, |
1130 | &bus_attr_poll_timeout, | 1229 | &bus_attr_poll_timeout, |
1230 | &bus_attr_ap_max_domain_id, | ||
1131 | NULL, | 1231 | NULL, |
1132 | }; | 1232 | }; |
1133 | 1233 | ||
1134 | static inline int ap_test_config(unsigned int *field, unsigned int nr) | ||
1135 | { | ||
1136 | if (nr > 0xFFu) | ||
1137 | return 0; | ||
1138 | return ap_test_bit((field + (nr >> 5)), (nr & 0x1f)); | ||
1139 | } | ||
1140 | |||
1141 | /* | ||
1142 | * ap_test_config_card_id(): Test, whether an AP card ID is configured. | ||
1143 | * @id AP card ID | ||
1144 | * | ||
1145 | * Returns 0 if the card is not configured | ||
1146 | * 1 if the card is configured or | ||
1147 | * if the configuration information is not available | ||
1148 | */ | ||
1149 | static inline int ap_test_config_card_id(unsigned int id) | ||
1150 | { | ||
1151 | if (!ap_configuration) | ||
1152 | return 1; | ||
1153 | return ap_test_config(ap_configuration->apm, id); | ||
1154 | } | ||
1155 | |||
1156 | /* | ||
1157 | * ap_test_config_domain(): Test, whether an AP usage domain is configured. | ||
1158 | * @domain AP usage domain ID | ||
1159 | * | ||
1160 | * Returns 0 if the usage domain is not configured | ||
1161 | * 1 if the usage domain is configured or | ||
1162 | * if the configuration information is not available | ||
1163 | */ | ||
1164 | static inline int ap_test_config_domain(unsigned int domain) | ||
1165 | { | ||
1166 | if (!ap_configuration) /* QCI not supported */ | ||
1167 | if (domain < 16) | ||
1168 | return 1; /* then domains 0...15 are configured */ | ||
1169 | else | ||
1170 | return 0; | ||
1171 | else | ||
1172 | return ap_test_config(ap_configuration->aqm, domain); | ||
1173 | } | ||
1174 | |||
1175 | /** | 1234 | /** |
1176 | * ap_query_configuration(): Query AP configuration information. | 1235 | * ap_query_configuration(): Query AP configuration information. |
1177 | * | 1236 | * |
@@ -1434,9 +1493,6 @@ static void ap_scan_bus(struct work_struct *unused) | |||
1434 | continue; | 1493 | continue; |
1435 | } | 1494 | } |
1436 | break; | 1495 | break; |
1437 | case 11: | ||
1438 | ap_dev->device_type = 10; | ||
1439 | break; | ||
1440 | default: | 1496 | default: |
1441 | ap_dev->device_type = device_type; | 1497 | ap_dev->device_type = device_type; |
1442 | } | 1498 | } |
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 055a0f956d17..2737d261a324 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h | |||
@@ -117,6 +117,7 @@ static inline int ap_test_bit(unsigned int *ptr, unsigned int nr) | |||
117 | #define AP_DEVICE_TYPE_CEX3A 8 | 117 | #define AP_DEVICE_TYPE_CEX3A 8 |
118 | #define AP_DEVICE_TYPE_CEX3C 9 | 118 | #define AP_DEVICE_TYPE_CEX3C 9 |
119 | #define AP_DEVICE_TYPE_CEX4 10 | 119 | #define AP_DEVICE_TYPE_CEX4 10 |
120 | #define AP_DEVICE_TYPE_CEX5 11 | ||
120 | 121 | ||
121 | /* | 122 | /* |
122 | * Known function facilities | 123 | * Known function facilities |
diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h index b3d496bfaa7e..750876891931 100644 --- a/drivers/s390/crypto/zcrypt_api.h +++ b/drivers/s390/crypto/zcrypt_api.h | |||
@@ -75,6 +75,7 @@ struct ica_z90_status { | |||
75 | #define ZCRYPT_CEX3C 7 | 75 | #define ZCRYPT_CEX3C 7 |
76 | #define ZCRYPT_CEX3A 8 | 76 | #define ZCRYPT_CEX3A 8 |
77 | #define ZCRYPT_CEX4 10 | 77 | #define ZCRYPT_CEX4 10 |
78 | #define ZCRYPT_CEX5 11 | ||
78 | 79 | ||
79 | /** | 80 | /** |
80 | * Large random numbers are pulled in 4096 byte chunks from the crypto cards | 81 | * Large random numbers are pulled in 4096 byte chunks from the crypto cards |
diff --git a/drivers/s390/crypto/zcrypt_cex4.c b/drivers/s390/crypto/zcrypt_cex4.c index 569f8b1d86c0..71e698b85772 100644 --- a/drivers/s390/crypto/zcrypt_cex4.c +++ b/drivers/s390/crypto/zcrypt_cex4.c | |||
@@ -26,6 +26,10 @@ | |||
26 | 26 | ||
27 | #define CEX4A_SPEED_RATING 900 /* TODO new card, new speed rating */ | 27 | #define CEX4A_SPEED_RATING 900 /* TODO new card, new speed rating */ |
28 | #define CEX4C_SPEED_RATING 6500 /* TODO new card, new speed rating */ | 28 | #define CEX4C_SPEED_RATING 6500 /* TODO new card, new speed rating */ |
29 | #define CEX4P_SPEED_RATING 7000 /* TODO new card, new speed rating */ | ||
30 | #define CEX5A_SPEED_RATING 450 /* TODO new card, new speed rating */ | ||
31 | #define CEX5C_SPEED_RATING 3250 /* TODO new card, new speed rating */ | ||
32 | #define CEX5P_SPEED_RATING 3500 /* TODO new card, new speed rating */ | ||
29 | 33 | ||
30 | #define CEX4A_MAX_MESSAGE_SIZE MSGTYPE50_CRB3_MAX_MSG_SIZE | 34 | #define CEX4A_MAX_MESSAGE_SIZE MSGTYPE50_CRB3_MAX_MSG_SIZE |
31 | #define CEX4C_MAX_MESSAGE_SIZE MSGTYPE06_MAX_MSG_SIZE | 35 | #define CEX4C_MAX_MESSAGE_SIZE MSGTYPE06_MAX_MSG_SIZE |
@@ -39,6 +43,7 @@ | |||
39 | 43 | ||
40 | static struct ap_device_id zcrypt_cex4_ids[] = { | 44 | static struct ap_device_id zcrypt_cex4_ids[] = { |
41 | { AP_DEVICE(AP_DEVICE_TYPE_CEX4) }, | 45 | { AP_DEVICE(AP_DEVICE_TYPE_CEX4) }, |
46 | { AP_DEVICE(AP_DEVICE_TYPE_CEX5) }, | ||
42 | { /* end of list */ }, | 47 | { /* end of list */ }, |
43 | }; | 48 | }; |
44 | 49 | ||
@@ -70,11 +75,18 @@ static int zcrypt_cex4_probe(struct ap_device *ap_dev) | |||
70 | 75 | ||
71 | switch (ap_dev->device_type) { | 76 | switch (ap_dev->device_type) { |
72 | case AP_DEVICE_TYPE_CEX4: | 77 | case AP_DEVICE_TYPE_CEX4: |
78 | case AP_DEVICE_TYPE_CEX5: | ||
73 | if (ap_test_bit(&ap_dev->functions, AP_FUNC_ACCEL)) { | 79 | if (ap_test_bit(&ap_dev->functions, AP_FUNC_ACCEL)) { |
74 | zdev = zcrypt_device_alloc(CEX4A_MAX_MESSAGE_SIZE); | 80 | zdev = zcrypt_device_alloc(CEX4A_MAX_MESSAGE_SIZE); |
75 | if (!zdev) | 81 | if (!zdev) |
76 | return -ENOMEM; | 82 | return -ENOMEM; |
77 | zdev->type_string = "CEX4A"; | 83 | if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) { |
84 | zdev->type_string = "CEX4A"; | ||
85 | zdev->speed_rating = CEX4A_SPEED_RATING; | ||
86 | } else { | ||
87 | zdev->type_string = "CEX5A"; | ||
88 | zdev->speed_rating = CEX5A_SPEED_RATING; | ||
89 | } | ||
78 | zdev->user_space_type = ZCRYPT_CEX3A; | 90 | zdev->user_space_type = ZCRYPT_CEX3A; |
79 | zdev->min_mod_size = CEX4A_MIN_MOD_SIZE; | 91 | zdev->min_mod_size = CEX4A_MIN_MOD_SIZE; |
80 | if (ap_test_bit(&ap_dev->functions, AP_FUNC_MEX4K) && | 92 | if (ap_test_bit(&ap_dev->functions, AP_FUNC_MEX4K) && |
@@ -90,33 +102,42 @@ static int zcrypt_cex4_probe(struct ap_device *ap_dev) | |||
90 | CEX4A_MAX_MOD_SIZE_2K; | 102 | CEX4A_MAX_MOD_SIZE_2K; |
91 | } | 103 | } |
92 | zdev->short_crt = 1; | 104 | zdev->short_crt = 1; |
93 | zdev->speed_rating = CEX4A_SPEED_RATING; | ||
94 | zdev->ops = zcrypt_msgtype_request(MSGTYPE50_NAME, | 105 | zdev->ops = zcrypt_msgtype_request(MSGTYPE50_NAME, |
95 | MSGTYPE50_VARIANT_DEFAULT); | 106 | MSGTYPE50_VARIANT_DEFAULT); |
96 | } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_COPRO)) { | 107 | } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_COPRO)) { |
97 | zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE); | 108 | zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE); |
98 | if (!zdev) | 109 | if (!zdev) |
99 | return -ENOMEM; | 110 | return -ENOMEM; |
100 | zdev->type_string = "CEX4C"; | 111 | if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) { |
112 | zdev->type_string = "CEX4C"; | ||
113 | zdev->speed_rating = CEX4C_SPEED_RATING; | ||
114 | } else { | ||
115 | zdev->type_string = "CEX5C"; | ||
116 | zdev->speed_rating = CEX5C_SPEED_RATING; | ||
117 | } | ||
101 | zdev->user_space_type = ZCRYPT_CEX3C; | 118 | zdev->user_space_type = ZCRYPT_CEX3C; |
102 | zdev->min_mod_size = CEX4C_MIN_MOD_SIZE; | 119 | zdev->min_mod_size = CEX4C_MIN_MOD_SIZE; |
103 | zdev->max_mod_size = CEX4C_MAX_MOD_SIZE; | 120 | zdev->max_mod_size = CEX4C_MAX_MOD_SIZE; |
104 | zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE; | 121 | zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE; |
105 | zdev->short_crt = 0; | 122 | zdev->short_crt = 0; |
106 | zdev->speed_rating = CEX4C_SPEED_RATING; | ||
107 | zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, | 123 | zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, |
108 | MSGTYPE06_VARIANT_DEFAULT); | 124 | MSGTYPE06_VARIANT_DEFAULT); |
109 | } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_EP11)) { | 125 | } else if (ap_test_bit(&ap_dev->functions, AP_FUNC_EP11)) { |
110 | zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE); | 126 | zdev = zcrypt_device_alloc(CEX4C_MAX_MESSAGE_SIZE); |
111 | if (!zdev) | 127 | if (!zdev) |
112 | return -ENOMEM; | 128 | return -ENOMEM; |
113 | zdev->type_string = "CEX4P"; | 129 | if (ap_dev->device_type == AP_DEVICE_TYPE_CEX4) { |
130 | zdev->type_string = "CEX4P"; | ||
131 | zdev->speed_rating = CEX4P_SPEED_RATING; | ||
132 | } else { | ||
133 | zdev->type_string = "CEX5P"; | ||
134 | zdev->speed_rating = CEX5P_SPEED_RATING; | ||
135 | } | ||
114 | zdev->user_space_type = ZCRYPT_CEX4; | 136 | zdev->user_space_type = ZCRYPT_CEX4; |
115 | zdev->min_mod_size = CEX4C_MIN_MOD_SIZE; | 137 | zdev->min_mod_size = CEX4C_MIN_MOD_SIZE; |
116 | zdev->max_mod_size = CEX4C_MAX_MOD_SIZE; | 138 | zdev->max_mod_size = CEX4C_MAX_MOD_SIZE; |
117 | zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE; | 139 | zdev->max_exp_bit_length = CEX4C_MAX_MOD_SIZE; |
118 | zdev->short_crt = 0; | 140 | zdev->short_crt = 0; |
119 | zdev->speed_rating = CEX4C_SPEED_RATING; | ||
120 | zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, | 141 | zdev->ops = zcrypt_msgtype_request(MSGTYPE06_NAME, |
121 | MSGTYPE06_VARIANT_EP11); | 142 | MSGTYPE06_VARIANT_EP11); |
122 | } | 143 | } |