aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 17:20:19 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2012-12-13 17:20:19 -0500
commitc7708fac5a878d6e0f2de0aa19f9749cff4f707f (patch)
tree21a59cbe503ca526697f7d0bce5e0e30980bcbc0 /drivers/s390
parent3127f23f013eabe9b58132c05061684c49146ba3 (diff)
parent6726a807c38d7fd09bc23a0adc738efec6ff9492 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 update from Martin Schwidefsky: "Add support to generate code for the latest machine zEC12, MOD and XOR instruction support for the BPF jit compiler, the dasd safe offline feature and the big one: the s390 architecture gets PCI support!! Right before the world ends on the 21st ;-)" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (41 commits) s390/qdio: rename the misleading PCI flag of qdio devices s390/pci: remove obsolete email addresses s390/pci: speed up __iowrite64_copy by using pci store block insn s390/pci: enable NEED_DMA_MAP_STATE s390/pci: no msleep in potential IRQ context s390/pci: fix potential NULL pointer dereference in dma_free_seg_table() s390/pci: use kmem_cache_zalloc instead of kmem_cache_alloc/memset s390/bpf,jit: add support for XOR instruction s390/bpf,jit: add support MOD instruction s390/cio: fix pgid reserved check vga: compile fix, disable vga for s390 s390/pci: add PCI Kconfig options s390/pci: s390 specific PCI sysfs attributes s390/pci: PCI hotplug support via SCLP s390/pci: CHSC PCI support for error and availability events s390/pci: DMA support s390/pci: PCI adapter interrupts for MSI/MSI-X s390/bitops: find leftmost bit instruction support s390/pci: CLP interface s390/pci: base support ...
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c97
-rw-r--r--drivers/s390/block/dasd_devmap.c34
-rw-r--r--drivers/s390/block/dasd_eckd.c92
-rw-r--r--drivers/s390/block/dasd_fba.c23
-rw-r--r--drivers/s390/block/dasd_int.h2
-rw-r--r--drivers/s390/block/dasd_ioctl.c11
-rw-r--r--drivers/s390/char/sclp.h3
-rw-r--r--drivers/s390/char/sclp_cmd.c81
-rw-r--r--drivers/s390/cio/ccwgroup.c26
-rw-r--r--drivers/s390/cio/chsc.c156
-rw-r--r--drivers/s390/cio/device.c11
-rw-r--r--drivers/s390/cio/device.h2
-rw-r--r--drivers/s390/cio/device_ops.c17
-rw-r--r--drivers/s390/cio/device_pgid.c10
-rw-r--r--drivers/s390/cio/qdio_main.c52
-rw-r--r--drivers/s390/cio/qdio_setup.c9
-rw-r--r--drivers/s390/cio/qdio_thinint.c2
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype50.c68
-rw-r--r--drivers/s390/crypto/zcrypt_msgtype50.h2
19 files changed, 443 insertions, 255 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 0595c763dafd..29225e1c159c 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -349,6 +349,16 @@ static int dasd_state_basic_to_ready(struct dasd_device *device)
349 return rc; 349 return rc;
350} 350}
351 351
352static inline
353int _wait_for_empty_queues(struct dasd_device *device)
354{
355 if (device->block)
356 return list_empty(&device->ccw_queue) &&
357 list_empty(&device->block->ccw_queue);
358 else
359 return list_empty(&device->ccw_queue);
360}
361
352/* 362/*
353 * Remove device from block device layer. Destroy dirty buffers. 363 * Remove device from block device layer. Destroy dirty buffers.
354 * Forget format information. Check if the target level is basic 364 * Forget format information. Check if the target level is basic
@@ -1841,6 +1851,13 @@ static void __dasd_device_check_expire(struct dasd_device *device)
1841 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist); 1851 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, devlist);
1842 if ((cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) && 1852 if ((cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) &&
1843 (time_after_eq(jiffies, cqr->expires + cqr->starttime))) { 1853 (time_after_eq(jiffies, cqr->expires + cqr->starttime))) {
1854 if (test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) {
1855 /*
1856 * IO in safe offline processing should not
1857 * run out of retries
1858 */
1859 cqr->retries++;
1860 }
1844 if (device->discipline->term_IO(cqr) != 0) { 1861 if (device->discipline->term_IO(cqr) != 0) {
1845 /* Hmpf, try again in 5 sec */ 1862 /* Hmpf, try again in 5 sec */
1846 dev_err(&device->cdev->dev, 1863 dev_err(&device->cdev->dev,
@@ -3024,11 +3041,11 @@ void dasd_generic_remove(struct ccw_device *cdev)
3024 3041
3025 cdev->handler = NULL; 3042 cdev->handler = NULL;
3026 3043
3027 dasd_remove_sysfs_files(cdev);
3028 device = dasd_device_from_cdev(cdev); 3044 device = dasd_device_from_cdev(cdev);
3029 if (IS_ERR(device)) 3045 if (IS_ERR(device))
3030 return; 3046 return;
3031 if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags)) { 3047 if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags) &&
3048 !test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) {
3032 /* Already doing offline processing */ 3049 /* Already doing offline processing */
3033 dasd_put_device(device); 3050 dasd_put_device(device);
3034 return; 3051 return;
@@ -3048,6 +3065,8 @@ void dasd_generic_remove(struct ccw_device *cdev)
3048 */ 3065 */
3049 if (block) 3066 if (block)
3050 dasd_free_block(block); 3067 dasd_free_block(block);
3068
3069 dasd_remove_sysfs_files(cdev);
3051} 3070}
3052 3071
3053/* 3072/*
@@ -3126,16 +3145,13 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
3126{ 3145{
3127 struct dasd_device *device; 3146 struct dasd_device *device;
3128 struct dasd_block *block; 3147 struct dasd_block *block;
3129 int max_count, open_count; 3148 int max_count, open_count, rc;
3130 3149
3150 rc = 0;
3131 device = dasd_device_from_cdev(cdev); 3151 device = dasd_device_from_cdev(cdev);
3132 if (IS_ERR(device)) 3152 if (IS_ERR(device))
3133 return PTR_ERR(device); 3153 return PTR_ERR(device);
3134 if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags)) { 3154
3135 /* Already doing offline processing */
3136 dasd_put_device(device);
3137 return 0;
3138 }
3139 /* 3155 /*
3140 * We must make sure that this device is currently not in use. 3156 * We must make sure that this device is currently not in use.
3141 * The open_count is increased for every opener, that includes 3157 * The open_count is increased for every opener, that includes
@@ -3159,6 +3175,54 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
3159 return -EBUSY; 3175 return -EBUSY;
3160 } 3176 }
3161 } 3177 }
3178
3179 if (test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) {
3180 /*
3181 * safe offline allready running
3182 * could only be called by normal offline so safe_offline flag
3183 * needs to be removed to run normal offline and kill all I/O
3184 */
3185 if (test_and_set_bit(DASD_FLAG_OFFLINE, &device->flags)) {
3186 /* Already doing normal offline processing */
3187 dasd_put_device(device);
3188 return -EBUSY;
3189 } else
3190 clear_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags);
3191
3192 } else
3193 if (test_bit(DASD_FLAG_OFFLINE, &device->flags)) {
3194 /* Already doing offline processing */
3195 dasd_put_device(device);
3196 return -EBUSY;
3197 }
3198
3199 /*
3200 * if safe_offline called set safe_offline_running flag and
3201 * clear safe_offline so that a call to normal offline
3202 * can overrun safe_offline processing
3203 */
3204 if (test_and_clear_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags) &&
3205 !test_and_set_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) {
3206 /*
3207 * If we want to set the device safe offline all IO operations
3208 * should be finished before continuing the offline process
3209 * so sync bdev first and then wait for our queues to become
3210 * empty
3211 */
3212 /* sync blockdev and partitions */
3213 rc = fsync_bdev(device->block->bdev);
3214 if (rc != 0)
3215 goto interrupted;
3216
3217 /* schedule device tasklet and wait for completion */
3218 dasd_schedule_device_bh(device);
3219 rc = wait_event_interruptible(shutdown_waitq,
3220 _wait_for_empty_queues(device));
3221 if (rc != 0)
3222 goto interrupted;
3223 }
3224
3225 set_bit(DASD_FLAG_OFFLINE, &device->flags);
3162 dasd_set_target_state(device, DASD_STATE_NEW); 3226 dasd_set_target_state(device, DASD_STATE_NEW);
3163 /* dasd_delete_device destroys the device reference. */ 3227 /* dasd_delete_device destroys the device reference. */
3164 block = device->block; 3228 block = device->block;
@@ -3170,6 +3234,14 @@ int dasd_generic_set_offline(struct ccw_device *cdev)
3170 if (block) 3234 if (block)
3171 dasd_free_block(block); 3235 dasd_free_block(block);
3172 return 0; 3236 return 0;
3237
3238interrupted:
3239 /* interrupted by signal */
3240 clear_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags);
3241 clear_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags);
3242 clear_bit(DASD_FLAG_OFFLINE, &device->flags);
3243 dasd_put_device(device);
3244 return rc;
3173} 3245}
3174 3246
3175int dasd_generic_last_path_gone(struct dasd_device *device) 3247int dasd_generic_last_path_gone(struct dasd_device *device)
@@ -3489,15 +3561,6 @@ char *dasd_get_sense(struct irb *irb)
3489} 3561}
3490EXPORT_SYMBOL_GPL(dasd_get_sense); 3562EXPORT_SYMBOL_GPL(dasd_get_sense);
3491 3563
3492static inline int _wait_for_empty_queues(struct dasd_device *device)
3493{
3494 if (device->block)
3495 return list_empty(&device->ccw_queue) &&
3496 list_empty(&device->block->ccw_queue);
3497 else
3498 return list_empty(&device->ccw_queue);
3499}
3500
3501void dasd_generic_shutdown(struct ccw_device *cdev) 3564void dasd_generic_shutdown(struct ccw_device *cdev)
3502{ 3565{
3503 struct dasd_device *device; 3566 struct dasd_device *device;
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 20cfd028edcf..c196827c228f 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -952,6 +952,39 @@ static DEVICE_ATTR(raw_track_access, 0644, dasd_use_raw_show,
952 dasd_use_raw_store); 952 dasd_use_raw_store);
953 953
954static ssize_t 954static ssize_t
955dasd_safe_offline_store(struct device *dev, struct device_attribute *attr,
956 const char *buf, size_t count)
957{
958 struct ccw_device *cdev = to_ccwdev(dev);
959 struct dasd_device *device;
960 int rc;
961
962 device = dasd_device_from_cdev(cdev);
963 if (IS_ERR(device)) {
964 rc = PTR_ERR(device);
965 goto out;
966 }
967
968 if (test_bit(DASD_FLAG_OFFLINE, &device->flags) ||
969 test_bit(DASD_FLAG_SAFE_OFFLINE_RUNNING, &device->flags)) {
970 /* Already doing offline processing */
971 dasd_put_device(device);
972 rc = -EBUSY;
973 goto out;
974 }
975
976 set_bit(DASD_FLAG_SAFE_OFFLINE, &device->flags);
977 dasd_put_device(device);
978
979 rc = ccw_device_set_offline(cdev);
980
981out:
982 return rc ? rc : count;
983}
984
985static DEVICE_ATTR(safe_offline, 0200, NULL, dasd_safe_offline_store);
986
987static ssize_t
955dasd_discipline_show(struct device *dev, struct device_attribute *attr, 988dasd_discipline_show(struct device *dev, struct device_attribute *attr,
956 char *buf) 989 char *buf)
957{ 990{
@@ -1320,6 +1353,7 @@ static struct attribute * dasd_attrs[] = {
1320 &dev_attr_expires.attr, 1353 &dev_attr_expires.attr,
1321 &dev_attr_reservation_policy.attr, 1354 &dev_attr_reservation_policy.attr,
1322 &dev_attr_last_known_reservation_state.attr, 1355 &dev_attr_last_known_reservation_state.attr,
1356 &dev_attr_safe_offline.attr,
1323 NULL, 1357 NULL,
1324}; 1358};
1325 1359
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 108332b44d98..806fe912d6e7 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -1026,7 +1026,7 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
1026{ 1026{
1027 void *conf_data; 1027 void *conf_data;
1028 int conf_len, conf_data_saved; 1028 int conf_len, conf_data_saved;
1029 int rc; 1029 int rc, path_err;
1030 __u8 lpm, opm; 1030 __u8 lpm, opm;
1031 struct dasd_eckd_private *private, path_private; 1031 struct dasd_eckd_private *private, path_private;
1032 struct dasd_path *path_data; 1032 struct dasd_path *path_data;
@@ -1037,6 +1037,7 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
1037 path_data = &device->path_data; 1037 path_data = &device->path_data;
1038 opm = ccw_device_get_path_mask(device->cdev); 1038 opm = ccw_device_get_path_mask(device->cdev);
1039 conf_data_saved = 0; 1039 conf_data_saved = 0;
1040 path_err = 0;
1040 /* get configuration data per operational path */ 1041 /* get configuration data per operational path */
1041 for (lpm = 0x80; lpm; lpm>>= 1) { 1042 for (lpm = 0x80; lpm; lpm>>= 1) {
1042 if (!(lpm & opm)) 1043 if (!(lpm & opm))
@@ -1122,7 +1123,8 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
1122 "the same device, path %02X leads to " 1123 "the same device, path %02X leads to "
1123 "device %s instead of %s\n", lpm, 1124 "device %s instead of %s\n", lpm,
1124 print_path_uid, print_device_uid); 1125 print_path_uid, print_device_uid);
1125 return -EINVAL; 1126 path_err = -EINVAL;
1127 continue;
1126 } 1128 }
1127 1129
1128 path_private.conf_data = NULL; 1130 path_private.conf_data = NULL;
@@ -1142,7 +1144,7 @@ static int dasd_eckd_read_conf(struct dasd_device *device)
1142 kfree(conf_data); 1144 kfree(conf_data);
1143 } 1145 }
1144 1146
1145 return 0; 1147 return path_err;
1146} 1148}
1147 1149
1148static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm) 1150static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm)
@@ -3847,7 +3849,7 @@ dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page)
3847 3849
3848 len = 0; 3850 len = 0;
3849 while (from <= to) { 3851 while (from <= to) {
3850 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3852 len += sprintf(page + len, PRINTK_HEADER
3851 " CCW %p: %08X %08X DAT:", 3853 " CCW %p: %08X %08X DAT:",
3852 from, ((int *) from)[0], ((int *) from)[1]); 3854 from, ((int *) from)[0], ((int *) from)[1]);
3853 3855
@@ -3908,23 +3910,23 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
3908 return; 3910 return;
3909 } 3911 }
3910 /* dump the sense data */ 3912 /* dump the sense data */
3911 len = sprintf(page, KERN_ERR PRINTK_HEADER 3913 len = sprintf(page, PRINTK_HEADER
3912 " I/O status report for device %s:\n", 3914 " I/O status report for device %s:\n",
3913 dev_name(&device->cdev->dev)); 3915 dev_name(&device->cdev->dev));
3914 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3916 len += sprintf(page + len, PRINTK_HEADER
3915 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X " 3917 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X "
3916 "CS:%02X RC:%d\n", 3918 "CS:%02X RC:%d\n",
3917 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw), 3919 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw),
3918 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw), 3920 scsw_actl(&irb->scsw), scsw_stctl(&irb->scsw),
3919 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw), 3921 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw),
3920 req ? req->intrc : 0); 3922 req ? req->intrc : 0);
3921 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3923 len += sprintf(page + len, PRINTK_HEADER
3922 " device %s: Failing CCW: %p\n", 3924 " device %s: Failing CCW: %p\n",
3923 dev_name(&device->cdev->dev), 3925 dev_name(&device->cdev->dev),
3924 (void *) (addr_t) irb->scsw.cmd.cpa); 3926 (void *) (addr_t) irb->scsw.cmd.cpa);
3925 if (irb->esw.esw0.erw.cons) { 3927 if (irb->esw.esw0.erw.cons) {
3926 for (sl = 0; sl < 4; sl++) { 3928 for (sl = 0; sl < 4; sl++) {
3927 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 3929 len += sprintf(page + len, PRINTK_HEADER
3928 " Sense(hex) %2d-%2d:", 3930 " Sense(hex) %2d-%2d:",
3929 (8 * sl), ((8 * sl) + 7)); 3931 (8 * sl), ((8 * sl) + 7));
3930 3932
@@ -3937,23 +3939,23 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
3937 3939
3938 if (irb->ecw[27] & DASD_SENSE_BIT_0) { 3940 if (irb->ecw[27] & DASD_SENSE_BIT_0) {
3939 /* 24 Byte Sense Data */ 3941 /* 24 Byte Sense Data */
3940 sprintf(page + len, KERN_ERR PRINTK_HEADER 3942 sprintf(page + len, PRINTK_HEADER
3941 " 24 Byte: %x MSG %x, " 3943 " 24 Byte: %x MSG %x, "
3942 "%s MSGb to SYSOP\n", 3944 "%s MSGb to SYSOP\n",
3943 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, 3945 irb->ecw[7] >> 4, irb->ecw[7] & 0x0f,
3944 irb->ecw[1] & 0x10 ? "" : "no"); 3946 irb->ecw[1] & 0x10 ? "" : "no");
3945 } else { 3947 } else {
3946 /* 32 Byte Sense Data */ 3948 /* 32 Byte Sense Data */
3947 sprintf(page + len, KERN_ERR PRINTK_HEADER 3949 sprintf(page + len, PRINTK_HEADER
3948 " 32 Byte: Format: %x " 3950 " 32 Byte: Format: %x "
3949 "Exception class %x\n", 3951 "Exception class %x\n",
3950 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); 3952 irb->ecw[6] & 0x0f, irb->ecw[22] >> 4);
3951 } 3953 }
3952 } else { 3954 } else {
3953 sprintf(page + len, KERN_ERR PRINTK_HEADER 3955 sprintf(page + len, PRINTK_HEADER
3954 " SORRY - NO VALID SENSE AVAILABLE\n"); 3956 " SORRY - NO VALID SENSE AVAILABLE\n");
3955 } 3957 }
3956 printk("%s", page); 3958 printk(KERN_ERR "%s", page);
3957 3959
3958 if (req) { 3960 if (req) {
3959 /* req == NULL for unsolicited interrupts */ 3961 /* req == NULL for unsolicited interrupts */
@@ -3962,10 +3964,10 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
3962 first = req->cpaddr; 3964 first = req->cpaddr;
3963 for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); 3965 for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
3964 to = min(first + 6, last); 3966 to = min(first + 6, last);
3965 len = sprintf(page, KERN_ERR PRINTK_HEADER 3967 len = sprintf(page, PRINTK_HEADER
3966 " Related CP in req: %p\n", req); 3968 " Related CP in req: %p\n", req);
3967 dasd_eckd_dump_ccw_range(first, to, page + len); 3969 dasd_eckd_dump_ccw_range(first, to, page + len);
3968 printk("%s", page); 3970 printk(KERN_ERR "%s", page);
3969 3971
3970 /* print failing CCW area (maximum 4) */ 3972 /* print failing CCW area (maximum 4) */
3971 /* scsw->cda is either valid or zero */ 3973 /* scsw->cda is either valid or zero */
@@ -3975,7 +3977,7 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
3975 irb->scsw.cmd.cpa; /* failing CCW */ 3977 irb->scsw.cmd.cpa; /* failing CCW */
3976 if (from < fail - 2) { 3978 if (from < fail - 2) {
3977 from = fail - 2; /* there is a gap - print header */ 3979 from = fail - 2; /* there is a gap - print header */
3978 len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n"); 3980 len += sprintf(page, PRINTK_HEADER "......\n");
3979 } 3981 }
3980 to = min(fail + 1, last); 3982 to = min(fail + 1, last);
3981 len += dasd_eckd_dump_ccw_range(from, to, page + len); 3983 len += dasd_eckd_dump_ccw_range(from, to, page + len);
@@ -3984,11 +3986,11 @@ static void dasd_eckd_dump_sense_ccw(struct dasd_device *device,
3984 from = max(from, ++to); 3986 from = max(from, ++to);
3985 if (from < last - 1) { 3987 if (from < last - 1) {
3986 from = last - 1; /* there is a gap - print header */ 3988 from = last - 1; /* there is a gap - print header */
3987 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 3989 len += sprintf(page + len, PRINTK_HEADER "......\n");
3988 } 3990 }
3989 len += dasd_eckd_dump_ccw_range(from, last, page + len); 3991 len += dasd_eckd_dump_ccw_range(from, last, page + len);
3990 if (len > 0) 3992 if (len > 0)
3991 printk("%s", page); 3993 printk(KERN_ERR "%s", page);
3992 } 3994 }
3993 free_page((unsigned long) page); 3995 free_page((unsigned long) page);
3994} 3996}
@@ -4012,10 +4014,10 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
4012 return; 4014 return;
4013 } 4015 }
4014 /* dump the sense data */ 4016 /* dump the sense data */
4015 len = sprintf(page, KERN_ERR PRINTK_HEADER 4017 len = sprintf(page, PRINTK_HEADER
4016 " I/O status report for device %s:\n", 4018 " I/O status report for device %s:\n",
4017 dev_name(&device->cdev->dev)); 4019 dev_name(&device->cdev->dev));
4018 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4020 len += sprintf(page + len, PRINTK_HEADER
4019 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X " 4021 " in req: %p CC:%02X FC:%02X AC:%02X SC:%02X DS:%02X "
4020 "CS:%02X fcxs:%02X schxs:%02X RC:%d\n", 4022 "CS:%02X fcxs:%02X schxs:%02X RC:%d\n",
4021 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw), 4023 req, scsw_cc(&irb->scsw), scsw_fctl(&irb->scsw),
@@ -4023,7 +4025,7 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
4023 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw), 4025 scsw_dstat(&irb->scsw), scsw_cstat(&irb->scsw),
4024 irb->scsw.tm.fcxs, irb->scsw.tm.schxs, 4026 irb->scsw.tm.fcxs, irb->scsw.tm.schxs,
4025 req ? req->intrc : 0); 4027 req ? req->intrc : 0);
4026 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4028 len += sprintf(page + len, PRINTK_HEADER
4027 " device %s: Failing TCW: %p\n", 4029 " device %s: Failing TCW: %p\n",
4028 dev_name(&device->cdev->dev), 4030 dev_name(&device->cdev->dev),
4029 (void *) (addr_t) irb->scsw.tm.tcw); 4031 (void *) (addr_t) irb->scsw.tm.tcw);
@@ -4035,43 +4037,42 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
4035 (struct tcw *)(unsigned long)irb->scsw.tm.tcw); 4037 (struct tcw *)(unsigned long)irb->scsw.tm.tcw);
4036 4038
4037 if (tsb) { 4039 if (tsb) {
4038 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4040 len += sprintf(page + len, PRINTK_HEADER
4039 " tsb->length %d\n", tsb->length); 4041 " tsb->length %d\n", tsb->length);
4040 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4042 len += sprintf(page + len, PRINTK_HEADER
4041 " tsb->flags %x\n", tsb->flags); 4043 " tsb->flags %x\n", tsb->flags);
4042 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4044 len += sprintf(page + len, PRINTK_HEADER
4043 " tsb->dcw_offset %d\n", tsb->dcw_offset); 4045 " tsb->dcw_offset %d\n", tsb->dcw_offset);
4044 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4046 len += sprintf(page + len, PRINTK_HEADER
4045 " tsb->count %d\n", tsb->count); 4047 " tsb->count %d\n", tsb->count);
4046 residual = tsb->count - 28; 4048 residual = tsb->count - 28;
4047 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4049 len += sprintf(page + len, PRINTK_HEADER
4048 " residual %d\n", residual); 4050 " residual %d\n", residual);
4049 4051
4050 switch (tsb->flags & 0x07) { 4052 switch (tsb->flags & 0x07) {
4051 case 1: /* tsa_iostat */ 4053 case 1: /* tsa_iostat */
4052 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4054 len += sprintf(page + len, PRINTK_HEADER
4053 " tsb->tsa.iostat.dev_time %d\n", 4055 " tsb->tsa.iostat.dev_time %d\n",
4054 tsb->tsa.iostat.dev_time); 4056 tsb->tsa.iostat.dev_time);
4055 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4057 len += sprintf(page + len, PRINTK_HEADER
4056 " tsb->tsa.iostat.def_time %d\n", 4058 " tsb->tsa.iostat.def_time %d\n",
4057 tsb->tsa.iostat.def_time); 4059 tsb->tsa.iostat.def_time);
4058 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4060 len += sprintf(page + len, PRINTK_HEADER
4059 " tsb->tsa.iostat.queue_time %d\n", 4061 " tsb->tsa.iostat.queue_time %d\n",
4060 tsb->tsa.iostat.queue_time); 4062 tsb->tsa.iostat.queue_time);
4061 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4063 len += sprintf(page + len, PRINTK_HEADER
4062 " tsb->tsa.iostat.dev_busy_time %d\n", 4064 " tsb->tsa.iostat.dev_busy_time %d\n",
4063 tsb->tsa.iostat.dev_busy_time); 4065 tsb->tsa.iostat.dev_busy_time);
4064 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4066 len += sprintf(page + len, PRINTK_HEADER
4065 " tsb->tsa.iostat.dev_act_time %d\n", 4067 " tsb->tsa.iostat.dev_act_time %d\n",
4066 tsb->tsa.iostat.dev_act_time); 4068 tsb->tsa.iostat.dev_act_time);
4067 sense = tsb->tsa.iostat.sense; 4069 sense = tsb->tsa.iostat.sense;
4068 break; 4070 break;
4069 case 2: /* ts_ddpc */ 4071 case 2: /* ts_ddpc */
4070 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4072 len += sprintf(page + len, PRINTK_HEADER
4071 " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc); 4073 " tsb->tsa.ddpc.rc %d\n", tsb->tsa.ddpc.rc);
4072 for (sl = 0; sl < 2; sl++) { 4074 for (sl = 0; sl < 2; sl++) {
4073 len += sprintf(page + len, 4075 len += sprintf(page + len, PRINTK_HEADER
4074 KERN_ERR PRINTK_HEADER
4075 " tsb->tsa.ddpc.rcq %2d-%2d: ", 4076 " tsb->tsa.ddpc.rcq %2d-%2d: ",
4076 (8 * sl), ((8 * sl) + 7)); 4077 (8 * sl), ((8 * sl) + 7));
4077 rcq = tsb->tsa.ddpc.rcq; 4078 rcq = tsb->tsa.ddpc.rcq;
@@ -4084,15 +4085,14 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
4084 sense = tsb->tsa.ddpc.sense; 4085 sense = tsb->tsa.ddpc.sense;
4085 break; 4086 break;
4086 case 3: /* tsa_intrg */ 4087 case 3: /* tsa_intrg */
4087 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 4088 len += sprintf(page + len, PRINTK_HEADER
4088 " tsb->tsa.intrg.: not supportet yet \n"); 4089 " tsb->tsa.intrg.: not supportet yet\n");
4089 break; 4090 break;
4090 } 4091 }
4091 4092
4092 if (sense) { 4093 if (sense) {
4093 for (sl = 0; sl < 4; sl++) { 4094 for (sl = 0; sl < 4; sl++) {
4094 len += sprintf(page + len, 4095 len += sprintf(page + len, PRINTK_HEADER
4095 KERN_ERR PRINTK_HEADER
4096 " Sense(hex) %2d-%2d:", 4096 " Sense(hex) %2d-%2d:",
4097 (8 * sl), ((8 * sl) + 7)); 4097 (8 * sl), ((8 * sl) + 7));
4098 for (sct = 0; sct < 8; sct++) { 4098 for (sct = 0; sct < 8; sct++) {
@@ -4104,27 +4104,27 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device,
4104 4104
4105 if (sense[27] & DASD_SENSE_BIT_0) { 4105 if (sense[27] & DASD_SENSE_BIT_0) {
4106 /* 24 Byte Sense Data */ 4106 /* 24 Byte Sense Data */
4107 sprintf(page + len, KERN_ERR PRINTK_HEADER 4107 sprintf(page + len, PRINTK_HEADER
4108 " 24 Byte: %x MSG %x, " 4108 " 24 Byte: %x MSG %x, "
4109 "%s MSGb to SYSOP\n", 4109 "%s MSGb to SYSOP\n",
4110 sense[7] >> 4, sense[7] & 0x0f, 4110 sense[7] >> 4, sense[7] & 0x0f,
4111 sense[1] & 0x10 ? "" : "no"); 4111 sense[1] & 0x10 ? "" : "no");
4112 } else { 4112 } else {
4113 /* 32 Byte Sense Data */ 4113 /* 32 Byte Sense Data */
4114 sprintf(page + len, KERN_ERR PRINTK_HEADER 4114 sprintf(page + len, PRINTK_HEADER
4115 " 32 Byte: Format: %x " 4115 " 32 Byte: Format: %x "
4116 "Exception class %x\n", 4116 "Exception class %x\n",
4117 sense[6] & 0x0f, sense[22] >> 4); 4117 sense[6] & 0x0f, sense[22] >> 4);
4118 } 4118 }
4119 } else { 4119 } else {
4120 sprintf(page + len, KERN_ERR PRINTK_HEADER 4120 sprintf(page + len, PRINTK_HEADER
4121 " SORRY - NO VALID SENSE AVAILABLE\n"); 4121 " SORRY - NO VALID SENSE AVAILABLE\n");
4122 } 4122 }
4123 } else { 4123 } else {
4124 sprintf(page + len, KERN_ERR PRINTK_HEADER 4124 sprintf(page + len, PRINTK_HEADER
4125 " SORRY - NO TSB DATA AVAILABLE\n"); 4125 " SORRY - NO TSB DATA AVAILABLE\n");
4126 } 4126 }
4127 printk("%s", page); 4127 printk(KERN_ERR "%s", page);
4128 free_page((unsigned long) page); 4128 free_page((unsigned long) page);
4129} 4129}
4130 4130
@@ -4161,9 +4161,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
4161 private = (struct dasd_eckd_private *) device->private; 4161 private = (struct dasd_eckd_private *) device->private;
4162 4162
4163 /* Read Configuration Data */ 4163 /* Read Configuration Data */
4164 rc = dasd_eckd_read_conf(device); 4164 dasd_eckd_read_conf(device);
4165 if (rc)
4166 goto out_err;
4167 4165
4168 dasd_eckd_get_uid(device, &temp_uid); 4166 dasd_eckd_get_uid(device, &temp_uid);
4169 /* Generate device unique id */ 4167 /* Generate device unique id */
@@ -4183,9 +4181,7 @@ static int dasd_eckd_restore_device(struct dasd_device *device)
4183 dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST); 4181 dasd_eckd_validate_server(device, DASD_CQR_FLAGS_FAILFAST);
4184 4182
4185 /* RE-Read Configuration Data */ 4183 /* RE-Read Configuration Data */
4186 rc = dasd_eckd_read_conf(device); 4184 dasd_eckd_read_conf(device);
4187 if (rc)
4188 goto out_err;
4189 4185
4190 /* Read Feature Codes */ 4186 /* Read Feature Codes */
4191 dasd_eckd_read_features(device); 4187 dasd_eckd_read_features(device);
diff --git a/drivers/s390/block/dasd_fba.c b/drivers/s390/block/dasd_fba.c
index fb7f3bdc6604..eb748507c7fa 100644
--- a/drivers/s390/block/dasd_fba.c
+++ b/drivers/s390/block/dasd_fba.c
@@ -479,19 +479,19 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
479 "No memory to dump sense data"); 479 "No memory to dump sense data");
480 return; 480 return;
481 } 481 }
482 len = sprintf(page, KERN_ERR PRINTK_HEADER 482 len = sprintf(page, PRINTK_HEADER
483 " I/O status report for device %s:\n", 483 " I/O status report for device %s:\n",
484 dev_name(&device->cdev->dev)); 484 dev_name(&device->cdev->dev));
485 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 485 len += sprintf(page + len, PRINTK_HEADER
486 " in req: %p CS: 0x%02X DS: 0x%02X\n", req, 486 " in req: %p CS: 0x%02X DS: 0x%02X\n", req,
487 irb->scsw.cmd.cstat, irb->scsw.cmd.dstat); 487 irb->scsw.cmd.cstat, irb->scsw.cmd.dstat);
488 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 488 len += sprintf(page + len, PRINTK_HEADER
489 " device %s: Failing CCW: %p\n", 489 " device %s: Failing CCW: %p\n",
490 dev_name(&device->cdev->dev), 490 dev_name(&device->cdev->dev),
491 (void *) (addr_t) irb->scsw.cmd.cpa); 491 (void *) (addr_t) irb->scsw.cmd.cpa);
492 if (irb->esw.esw0.erw.cons) { 492 if (irb->esw.esw0.erw.cons) {
493 for (sl = 0; sl < 4; sl++) { 493 for (sl = 0; sl < 4; sl++) {
494 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 494 len += sprintf(page + len, PRINTK_HEADER
495 " Sense(hex) %2d-%2d:", 495 " Sense(hex) %2d-%2d:",
496 (8 * sl), ((8 * sl) + 7)); 496 (8 * sl), ((8 * sl) + 7));
497 497
@@ -502,7 +502,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
502 len += sprintf(page + len, "\n"); 502 len += sprintf(page + len, "\n");
503 } 503 }
504 } else { 504 } else {
505 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 505 len += sprintf(page + len, PRINTK_HEADER
506 " SORRY - NO VALID SENSE AVAILABLE\n"); 506 " SORRY - NO VALID SENSE AVAILABLE\n");
507 } 507 }
508 printk(KERN_ERR "%s", page); 508 printk(KERN_ERR "%s", page);
@@ -512,10 +512,9 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
512 act = req->cpaddr; 512 act = req->cpaddr;
513 for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); 513 for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++);
514 end = min(act + 8, last); 514 end = min(act + 8, last);
515 len = sprintf(page, KERN_ERR PRINTK_HEADER 515 len = sprintf(page, PRINTK_HEADER " Related CP in req: %p\n", req);
516 " Related CP in req: %p\n", req);
517 while (act <= end) { 516 while (act <= end) {
518 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 517 len += sprintf(page + len, PRINTK_HEADER
519 " CCW %p: %08X %08X DAT:", 518 " CCW %p: %08X %08X DAT:",
520 act, ((int *) act)[0], ((int *) act)[1]); 519 act, ((int *) act)[0], ((int *) act)[1]);
521 for (count = 0; count < 32 && count < act->count; 520 for (count = 0; count < 32 && count < act->count;
@@ -533,11 +532,11 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
533 len = 0; 532 len = 0;
534 if (act < ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2) { 533 if (act < ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2) {
535 act = ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2; 534 act = ((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa) - 2;
536 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 535 len += sprintf(page + len, PRINTK_HEADER "......\n");
537 } 536 }
538 end = min((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa + 2, last); 537 end = min((struct ccw1 *)(addr_t) irb->scsw.cmd.cpa + 2, last);
539 while (act <= end) { 538 while (act <= end) {
540 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 539 len += sprintf(page + len, PRINTK_HEADER
541 " CCW %p: %08X %08X DAT:", 540 " CCW %p: %08X %08X DAT:",
542 act, ((int *) act)[0], ((int *) act)[1]); 541 act, ((int *) act)[0], ((int *) act)[1]);
543 for (count = 0; count < 32 && count < act->count; 542 for (count = 0; count < 32 && count < act->count;
@@ -552,10 +551,10 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req,
552 /* print last CCWs */ 551 /* print last CCWs */
553 if (act < last - 2) { 552 if (act < last - 2) {
554 act = last - 2; 553 act = last - 2;
555 len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); 554 len += sprintf(page + len, PRINTK_HEADER "......\n");
556 } 555 }
557 while (act <= last) { 556 while (act <= last) {
558 len += sprintf(page + len, KERN_ERR PRINTK_HEADER 557 len += sprintf(page + len, PRINTK_HEADER
559 " CCW %p: %08X %08X DAT:", 558 " CCW %p: %08X %08X DAT:",
560 act, ((int *) act)[0], ((int *) act)[1]); 559 act, ((int *) act)[0], ((int *) act)[1]);
561 for (count = 0; count < 32 && count < act->count; 560 for (count = 0; count < 32 && count < act->count;
diff --git a/drivers/s390/block/dasd_int.h b/drivers/s390/block/dasd_int.h
index 7ff93eea673d..899e3f5a56e5 100644
--- a/drivers/s390/block/dasd_int.h
+++ b/drivers/s390/block/dasd_int.h
@@ -516,6 +516,8 @@ struct dasd_block {
516#define DASD_FLAG_IS_RESERVED 7 /* The device is reserved */ 516#define DASD_FLAG_IS_RESERVED 7 /* The device is reserved */
517#define DASD_FLAG_LOCK_STOLEN 8 /* The device lock was stolen */ 517#define DASD_FLAG_LOCK_STOLEN 8 /* The device lock was stolen */
518#define DASD_FLAG_SUSPENDED 9 /* The device was suspended */ 518#define DASD_FLAG_SUSPENDED 9 /* The device was suspended */
519#define DASD_FLAG_SAFE_OFFLINE 10 /* safe offline processing requested*/
520#define DASD_FLAG_SAFE_OFFLINE_RUNNING 11 /* safe offline running */
519 521
520 522
521void dasd_put_device_wake(struct dasd_device *); 523void dasd_put_device_wake(struct dasd_device *);
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index 8252f37d04ed..03c0e0444553 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -19,6 +19,7 @@
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <asm/compat.h> 20#include <asm/compat.h>
21#include <asm/ccwdev.h> 21#include <asm/ccwdev.h>
22#include <asm/schid.h>
22#include <asm/cmb.h> 23#include <asm/cmb.h>
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24 25
@@ -308,11 +309,12 @@ static int dasd_ioctl_information(struct dasd_block *block,
308 unsigned int cmd, void __user *argp) 309 unsigned int cmd, void __user *argp)
309{ 310{
310 struct dasd_information2_t *dasd_info; 311 struct dasd_information2_t *dasd_info;
311 unsigned long flags; 312 struct subchannel_id sch_id;
312 int rc; 313 struct ccw_dev_id dev_id;
313 struct dasd_device *base; 314 struct dasd_device *base;
314 struct ccw_device *cdev; 315 struct ccw_device *cdev;
315 struct ccw_dev_id dev_id; 316 unsigned long flags;
317 int rc;
316 318
317 base = block->base; 319 base = block->base;
318 if (!base->discipline || !base->discipline->fill_info) 320 if (!base->discipline || !base->discipline->fill_info)
@@ -330,9 +332,10 @@ static int dasd_ioctl_information(struct dasd_block *block,
330 332
331 cdev = base->cdev; 333 cdev = base->cdev;
332 ccw_device_get_id(cdev, &dev_id); 334 ccw_device_get_id(cdev, &dev_id);
335 ccw_device_get_schid(cdev, &sch_id);
333 336
334 dasd_info->devno = dev_id.devno; 337 dasd_info->devno = dev_id.devno;
335 dasd_info->schid = _ccw_device_get_subchannel_number(base->cdev); 338 dasd_info->schid = sch_id.sch_no;
336 dasd_info->cu_type = cdev->id.cu_type; 339 dasd_info->cu_type = cdev->id.cu_type;
337 dasd_info->cu_model = cdev->id.cu_model; 340 dasd_info->cu_model = cdev->id.cu_model;
338 dasd_info->dev_type = cdev->id.dev_type; 341 dasd_info->dev_type = cdev->id.dev_type;
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index d7e97ae9ef6d..25bcd4c0ed82 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright IBM Corp. 1999, 2009 2 * Copyright IBM Corp. 1999,2012
3 * 3 *
4 * Author(s): Martin Peschke <mpeschke@de.ibm.com> 4 * Author(s): Martin Peschke <mpeschke@de.ibm.com>
5 * Martin Schwidefsky <schwidefsky@de.ibm.com> 5 * Martin Schwidefsky <schwidefsky@de.ibm.com>
@@ -103,6 +103,7 @@ extern u64 sclp_facilities;
103#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL) 103#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL)
104#define SCLP_HAS_CPU_INFO (sclp_facilities & 0x0800000000000000ULL) 104#define SCLP_HAS_CPU_INFO (sclp_facilities & 0x0800000000000000ULL)
105#define SCLP_HAS_CPU_RECONFIG (sclp_facilities & 0x0400000000000000ULL) 105#define SCLP_HAS_CPU_RECONFIG (sclp_facilities & 0x0400000000000000ULL)
106#define SCLP_HAS_PCI_RECONFIG (sclp_facilities & 0x0000000040000000ULL)
106 107
107 108
108struct gds_subvector { 109struct gds_subvector {
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 71ea923c322d..c44d13f607bc 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright IBM Corp. 2007, 2009 2 * Copyright IBM Corp. 2007,2012
3 * 3 *
4 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>, 4 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>,
5 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> 5 * Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
@@ -12,6 +12,7 @@
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/err.h> 14#include <linux/err.h>
15#include <linux/export.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/string.h> 17#include <linux/string.h>
17#include <linux/mm.h> 18#include <linux/mm.h>
@@ -19,10 +20,11 @@
19#include <linux/memory.h> 20#include <linux/memory.h>
20#include <linux/module.h> 21#include <linux/module.h>
21#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <asm/ctl_reg.h>
22#include <asm/chpid.h> 24#include <asm/chpid.h>
23#include <asm/sclp.h>
24#include <asm/setup.h> 25#include <asm/setup.h>
25#include <asm/ctl_reg.h> 26#include <asm/page.h>
27#include <asm/sclp.h>
26 28
27#include "sclp.h" 29#include "sclp.h"
28 30
@@ -400,17 +402,15 @@ out:
400 402
401static int sclp_assign_storage(u16 rn) 403static int sclp_assign_storage(u16 rn)
402{ 404{
403 unsigned long long start, address; 405 unsigned long long start;
404 int rc; 406 int rc;
405 407
406 rc = do_assign_storage(0x000d0001, rn); 408 rc = do_assign_storage(0x000d0001, rn);
407 if (rc) 409 if (rc)
408 goto out; 410 return rc;
409 start = address = rn2addr(rn); 411 start = rn2addr(rn);
410 for (; address < start + rzm; address += PAGE_SIZE) 412 storage_key_init_range(start, start + rzm);
411 page_set_storage_key(address, PAGE_DEFAULT_KEY, 0); 413 return 0;
412out:
413 return rc;
414} 414}
415 415
416static int sclp_unassign_storage(u16 rn) 416static int sclp_unassign_storage(u16 rn)
@@ -702,6 +702,67 @@ __initcall(sclp_detect_standby_memory);
702#endif /* CONFIG_MEMORY_HOTPLUG */ 702#endif /* CONFIG_MEMORY_HOTPLUG */
703 703
704/* 704/*
705 * PCI I/O adapter configuration related functions.
706 */
707#define SCLP_CMDW_CONFIGURE_PCI 0x001a0001
708#define SCLP_CMDW_DECONFIGURE_PCI 0x001b0001
709
710#define SCLP_RECONFIG_PCI_ATPYE 2
711
712struct pci_cfg_sccb {
713 struct sccb_header header;
714 u8 atype; /* adapter type */
715 u8 reserved1;
716 u16 reserved2;
717 u32 aid; /* adapter identifier */
718} __packed;
719
720static int do_pci_configure(sclp_cmdw_t cmd, u32 fid)
721{
722 struct pci_cfg_sccb *sccb;
723 int rc;
724
725 if (!SCLP_HAS_PCI_RECONFIG)
726 return -EOPNOTSUPP;
727
728 sccb = (struct pci_cfg_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
729 if (!sccb)
730 return -ENOMEM;
731
732 sccb->header.length = PAGE_SIZE;
733 sccb->atype = SCLP_RECONFIG_PCI_ATPYE;
734 sccb->aid = fid;
735 rc = do_sync_request(cmd, sccb);
736 if (rc)
737 goto out;
738 switch (sccb->header.response_code) {
739 case 0x0020:
740 case 0x0120:
741 break;
742 default:
743 pr_warn("configure PCI I/O adapter failed: cmd=0x%08x response=0x%04x\n",
744 cmd, sccb->header.response_code);
745 rc = -EIO;
746 break;
747 }
748out:
749 free_page((unsigned long) sccb);
750 return rc;
751}
752
753int sclp_pci_configure(u32 fid)
754{
755 return do_pci_configure(SCLP_CMDW_CONFIGURE_PCI, fid);
756}
757EXPORT_SYMBOL(sclp_pci_configure);
758
759int sclp_pci_deconfigure(u32 fid)
760{
761 return do_pci_configure(SCLP_CMDW_DECONFIGURE_PCI, fid);
762}
763EXPORT_SYMBOL(sclp_pci_deconfigure);
764
765/*
705 * Channel path configuration related functions. 766 * Channel path configuration related functions.
706 */ 767 */
707 768
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index 731470e68493..84846c2b96d3 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -65,10 +65,18 @@ static void __ccwgroup_remove_cdev_refs(struct ccwgroup_device *gdev)
65 } 65 }
66} 66}
67 67
68static int ccwgroup_set_online(struct ccwgroup_device *gdev) 68/**
69 * ccwgroup_set_online() - enable a ccwgroup device
70 * @gdev: target ccwgroup device
71 *
72 * This function attempts to put the ccwgroup device into the online state.
73 * Returns:
74 * %0 on success and a negative error value on failure.
75 */
76int ccwgroup_set_online(struct ccwgroup_device *gdev)
69{ 77{
70 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); 78 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
71 int ret = 0; 79 int ret = -EINVAL;
72 80
73 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0) 81 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
74 return -EAGAIN; 82 return -EAGAIN;
@@ -84,11 +92,20 @@ out:
84 atomic_set(&gdev->onoff, 0); 92 atomic_set(&gdev->onoff, 0);
85 return ret; 93 return ret;
86} 94}
95EXPORT_SYMBOL(ccwgroup_set_online);
87 96
88static int ccwgroup_set_offline(struct ccwgroup_device *gdev) 97/**
98 * ccwgroup_set_offline() - disable a ccwgroup device
99 * @gdev: target ccwgroup device
100 *
101 * This function attempts to put the ccwgroup device into the offline state.
102 * Returns:
103 * %0 on success and a negative error value on failure.
104 */
105int ccwgroup_set_offline(struct ccwgroup_device *gdev)
89{ 106{
90 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver); 107 struct ccwgroup_driver *gdrv = to_ccwgroupdrv(gdev->dev.driver);
91 int ret = 0; 108 int ret = -EINVAL;
92 109
93 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0) 110 if (atomic_cmpxchg(&gdev->onoff, 0, 1) != 0)
94 return -EAGAIN; 111 return -EAGAIN;
@@ -104,6 +121,7 @@ out:
104 atomic_set(&gdev->onoff, 0); 121 atomic_set(&gdev->onoff, 0);
105 return ret; 122 return ret;
106} 123}
124EXPORT_SYMBOL(ccwgroup_set_offline);
107 125
108static ssize_t ccwgroup_online_store(struct device *dev, 126static ssize_t ccwgroup_online_store(struct device *dev,
109 struct device_attribute *attr, 127 struct device_attribute *attr,
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 4d51a7c4eb8b..68e80e2734a4 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * S/390 common I/O routines -- channel subsystem call 2 * S/390 common I/O routines -- channel subsystem call
3 * 3 *
4 * Copyright IBM Corp. 1999, 2010 4 * Copyright IBM Corp. 1999,2012
5 * Author(s): Ingo Adlung (adlung@de.ibm.com) 5 * Author(s): Ingo Adlung (adlung@de.ibm.com)
6 * Cornelia Huck (cornelia.huck@de.ibm.com) 6 * Cornelia Huck (cornelia.huck@de.ibm.com)
7 * Arnd Bergmann (arndb@de.ibm.com) 7 * Arnd Bergmann (arndb@de.ibm.com)
@@ -14,6 +14,7 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/pci.h>
17 18
18#include <asm/cio.h> 19#include <asm/cio.h>
19#include <asm/chpid.h> 20#include <asm/chpid.h>
@@ -260,26 +261,45 @@ __get_chpid_from_lir(void *data)
260 return (u16) (lir->indesc[0]&0x000000ff); 261 return (u16) (lir->indesc[0]&0x000000ff);
261} 262}
262 263
263struct chsc_sei_area { 264struct chsc_sei_nt0_area {
264 struct chsc_header request; 265 u8 flags;
266 u8 vf; /* validity flags */
267 u8 rs; /* reporting source */
268 u8 cc; /* content code */
269 u16 fla; /* full link address */
270 u16 rsid; /* reporting source id */
265 u32 reserved1; 271 u32 reserved1;
266 u32 reserved2; 272 u32 reserved2;
267 u32 reserved3;
268 struct chsc_header response;
269 u32 reserved4;
270 u8 flags;
271 u8 vf; /* validity flags */
272 u8 rs; /* reporting source */
273 u8 cc; /* content code */
274 u16 fla; /* full link address */
275 u16 rsid; /* reporting source id */
276 u32 reserved5;
277 u32 reserved6;
278 u8 ccdf[4096 - 16 - 24]; /* content-code dependent field */
279 /* ccdf has to be big enough for a link-incident record */ 273 /* ccdf has to be big enough for a link-incident record */
280} __attribute__ ((packed)); 274 u8 ccdf[PAGE_SIZE - 24 - 16]; /* content-code dependent field */
281 275} __packed;
282static void chsc_process_sei_link_incident(struct chsc_sei_area *sei_area) 276
277struct chsc_sei_nt2_area {
278 u8 flags; /* p and v bit */
279 u8 reserved1;
280 u8 reserved2;
281 u8 cc; /* content code */
282 u32 reserved3[13];
283 u8 ccdf[PAGE_SIZE - 24 - 56]; /* content-code dependent field */
284} __packed;
285
286#define CHSC_SEI_NT0 0ULL
287#define CHSC_SEI_NT2 (1ULL << 61)
288
289struct chsc_sei {
290 struct chsc_header request;
291 u32 reserved1;
292 u64 ntsm; /* notification type mask */
293 struct chsc_header response;
294 u32 reserved2;
295 union {
296 struct chsc_sei_nt0_area nt0_area;
297 struct chsc_sei_nt2_area nt2_area;
298 u8 nt_area[PAGE_SIZE - 24];
299 } u;
300} __packed;
301
302static void chsc_process_sei_link_incident(struct chsc_sei_nt0_area *sei_area)
283{ 303{
284 struct chp_id chpid; 304 struct chp_id chpid;
285 int id; 305 int id;
@@ -298,7 +318,7 @@ static void chsc_process_sei_link_incident(struct chsc_sei_area *sei_area)
298 } 318 }
299} 319}
300 320
301static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area) 321static void chsc_process_sei_res_acc(struct chsc_sei_nt0_area *sei_area)
302{ 322{
303 struct chp_link link; 323 struct chp_link link;
304 struct chp_id chpid; 324 struct chp_id chpid;
@@ -330,7 +350,7 @@ static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area)
330 s390_process_res_acc(&link); 350 s390_process_res_acc(&link);
331} 351}
332 352
333static void chsc_process_sei_chp_avail(struct chsc_sei_area *sei_area) 353static void chsc_process_sei_chp_avail(struct chsc_sei_nt0_area *sei_area)
334{ 354{
335 struct channel_path *chp; 355 struct channel_path *chp;
336 struct chp_id chpid; 356 struct chp_id chpid;
@@ -366,7 +386,7 @@ struct chp_config_data {
366 u8 pc; 386 u8 pc;
367}; 387};
368 388
369static void chsc_process_sei_chp_config(struct chsc_sei_area *sei_area) 389static void chsc_process_sei_chp_config(struct chsc_sei_nt0_area *sei_area)
370{ 390{
371 struct chp_config_data *data; 391 struct chp_config_data *data;
372 struct chp_id chpid; 392 struct chp_id chpid;
@@ -398,7 +418,7 @@ static void chsc_process_sei_chp_config(struct chsc_sei_area *sei_area)
398 } 418 }
399} 419}
400 420
401static void chsc_process_sei_scm_change(struct chsc_sei_area *sei_area) 421static void chsc_process_sei_scm_change(struct chsc_sei_nt0_area *sei_area)
402{ 422{
403 int ret; 423 int ret;
404 424
@@ -412,13 +432,26 @@ static void chsc_process_sei_scm_change(struct chsc_sei_area *sei_area)
412 " failed (rc=%d).\n", ret); 432 " failed (rc=%d).\n", ret);
413} 433}
414 434
415static void chsc_process_sei(struct chsc_sei_area *sei_area) 435static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area)
416{ 436{
417 /* Check if we might have lost some information. */ 437#ifdef CONFIG_PCI
418 if (sei_area->flags & 0x40) { 438 switch (sei_area->cc) {
419 CIO_CRW_EVENT(2, "chsc: event overflow\n"); 439 case 1:
420 css_schedule_eval_all(); 440 zpci_event_error(sei_area->ccdf);
441 break;
442 case 2:
443 zpci_event_availability(sei_area->ccdf);
444 break;
445 default:
446 CIO_CRW_EVENT(2, "chsc: unhandled sei content code %d\n",
447 sei_area->cc);
448 break;
421 } 449 }
450#endif
451}
452
453static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area)
454{
422 /* which kind of information was stored? */ 455 /* which kind of information was stored? */
423 switch (sei_area->cc) { 456 switch (sei_area->cc) {
424 case 1: /* link incident*/ 457 case 1: /* link incident*/
@@ -443,9 +476,51 @@ static void chsc_process_sei(struct chsc_sei_area *sei_area)
443 } 476 }
444} 477}
445 478
479static int __chsc_process_crw(struct chsc_sei *sei, u64 ntsm)
480{
481 do {
482 memset(sei, 0, sizeof(*sei));
483 sei->request.length = 0x0010;
484 sei->request.code = 0x000e;
485 sei->ntsm = ntsm;
486
487 if (chsc(sei))
488 break;
489
490 if (sei->response.code == 0x0001) {
491 CIO_CRW_EVENT(2, "chsc: sei successful\n");
492
493 /* Check if we might have lost some information. */
494 if (sei->u.nt0_area.flags & 0x40) {
495 CIO_CRW_EVENT(2, "chsc: event overflow\n");
496 css_schedule_eval_all();
497 }
498
499 switch (sei->ntsm) {
500 case CHSC_SEI_NT0:
501 chsc_process_sei_nt0(&sei->u.nt0_area);
502 return 1;
503 case CHSC_SEI_NT2:
504 chsc_process_sei_nt2(&sei->u.nt2_area);
505 return 1;
506 default:
507 CIO_CRW_EVENT(2, "chsc: unhandled nt (nt=%08Lx)\n",
508 sei->ntsm);
509 return 0;
510 }
511 } else {
512 CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n",
513 sei->response.code);
514 break;
515 }
516 } while (sei->u.nt0_area.flags & 0x80);
517
518 return 0;
519}
520
446static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) 521static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
447{ 522{
448 struct chsc_sei_area *sei_area; 523 struct chsc_sei *sei;
449 524
450 if (overflow) { 525 if (overflow) {
451 css_schedule_eval_all(); 526 css_schedule_eval_all();
@@ -459,25 +534,18 @@ static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
459 return; 534 return;
460 /* Access to sei_page is serialized through machine check handler 535 /* Access to sei_page is serialized through machine check handler
461 * thread, so no need for locking. */ 536 * thread, so no need for locking. */
462 sei_area = sei_page; 537 sei = sei_page;
463 538
464 CIO_TRACE_EVENT(2, "prcss"); 539 CIO_TRACE_EVENT(2, "prcss");
465 do {
466 memset(sei_area, 0, sizeof(*sei_area));
467 sei_area->request.length = 0x0010;
468 sei_area->request.code = 0x000e;
469 if (chsc(sei_area))
470 break;
471 540
472 if (sei_area->response.code == 0x0001) { 541 /*
473 CIO_CRW_EVENT(4, "chsc: sei successful\n"); 542 * The ntsm does not allow to select NT0 and NT2 together. We need to
474 chsc_process_sei(sei_area); 543 * first check for NT2, than additionally for NT0...
475 } else { 544 */
476 CIO_CRW_EVENT(2, "chsc: sei failed (rc=%04x)\n", 545#ifdef CONFIG_PCI
477 sei_area->response.code); 546 if (!__chsc_process_crw(sei, CHSC_SEI_NT2))
478 break; 547#endif
479 } 548 __chsc_process_crw(sei, CHSC_SEI_NT0);
480 } while (sei_area->flags & 0x80);
481} 549}
482 550
483void chsc_chp_online(struct chp_id chpid) 551void chsc_chp_online(struct chp_id chpid)
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index fd3143c291c6..6995cff44636 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -2036,16 +2036,6 @@ void ccw_driver_unregister(struct ccw_driver *cdriver)
2036 driver_unregister(&cdriver->driver); 2036 driver_unregister(&cdriver->driver);
2037} 2037}
2038 2038
2039/* Helper func for qdio. */
2040struct subchannel_id
2041ccw_device_get_subchannel_id(struct ccw_device *cdev)
2042{
2043 struct subchannel *sch;
2044
2045 sch = to_subchannel(cdev->dev.parent);
2046 return sch->schid;
2047}
2048
2049static void ccw_device_todo(struct work_struct *work) 2039static void ccw_device_todo(struct work_struct *work)
2050{ 2040{
2051 struct ccw_device_private *priv; 2041 struct ccw_device_private *priv;
@@ -2138,4 +2128,3 @@ EXPORT_SYMBOL(ccw_device_set_offline);
2138EXPORT_SYMBOL(ccw_driver_register); 2128EXPORT_SYMBOL(ccw_driver_register);
2139EXPORT_SYMBOL(ccw_driver_unregister); 2129EXPORT_SYMBOL(ccw_driver_unregister);
2140EXPORT_SYMBOL(get_ccwdev_by_busid); 2130EXPORT_SYMBOL(get_ccwdev_by_busid);
2141EXPORT_SYMBOL_GPL(ccw_device_get_subchannel_id);
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 6bace6942396..2e575cff9845 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -142,9 +142,7 @@ int ccw_device_notify(struct ccw_device *, int);
142void ccw_device_set_disconnected(struct ccw_device *cdev); 142void ccw_device_set_disconnected(struct ccw_device *cdev);
143void ccw_device_set_notoper(struct ccw_device *cdev); 143void ccw_device_set_notoper(struct ccw_device *cdev);
144 144
145/* qdio needs this. */
146void ccw_device_set_timeout(struct ccw_device *, int); 145void ccw_device_set_timeout(struct ccw_device *, int);
147extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *);
148 146
149/* Channel measurement facility related */ 147/* Channel measurement facility related */
150void retry_set_schib(struct ccw_device *cdev); 148void retry_set_schib(struct ccw_device *cdev);
diff --git a/drivers/s390/cio/device_ops.c b/drivers/s390/cio/device_ops.c
index ec7fb6d3b479..c77b6e06bf64 100644
--- a/drivers/s390/cio/device_ops.c
+++ b/drivers/s390/cio/device_ops.c
@@ -755,14 +755,18 @@ int ccw_device_tm_intrg(struct ccw_device *cdev)
755} 755}
756EXPORT_SYMBOL(ccw_device_tm_intrg); 756EXPORT_SYMBOL(ccw_device_tm_intrg);
757 757
758// FIXME: these have to go: 758/**
759 759 * ccw_device_get_schid - obtain a subchannel id
760int 760 * @cdev: device to obtain the id for
761_ccw_device_get_subchannel_number(struct ccw_device *cdev) 761 * @schid: where to fill in the values
762 */
763void ccw_device_get_schid(struct ccw_device *cdev, struct subchannel_id *schid)
762{ 764{
763 return cdev->private->schid.sch_no; 765 struct subchannel *sch = to_subchannel(cdev->dev.parent);
764}
765 766
767 *schid = sch->schid;
768}
769EXPORT_SYMBOL_GPL(ccw_device_get_schid);
766 770
767MODULE_LICENSE("GPL"); 771MODULE_LICENSE("GPL");
768EXPORT_SYMBOL(ccw_device_set_options_mask); 772EXPORT_SYMBOL(ccw_device_set_options_mask);
@@ -777,5 +781,4 @@ EXPORT_SYMBOL(ccw_device_start_timeout_key);
777EXPORT_SYMBOL(ccw_device_start_key); 781EXPORT_SYMBOL(ccw_device_start_key);
778EXPORT_SYMBOL(ccw_device_get_ciw); 782EXPORT_SYMBOL(ccw_device_get_ciw);
779EXPORT_SYMBOL(ccw_device_get_path_mask); 783EXPORT_SYMBOL(ccw_device_get_path_mask);
780EXPORT_SYMBOL(_ccw_device_get_subchannel_number);
781EXPORT_SYMBOL_GPL(ccw_device_get_chp_desc); 784EXPORT_SYMBOL_GPL(ccw_device_get_chp_desc);
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index 368368fe04b2..908d287f66c1 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -234,7 +234,7 @@ static int pgid_cmp(struct pgid *p1, struct pgid *p2)
234 * Determine pathgroup state from PGID data. 234 * Determine pathgroup state from PGID data.
235 */ 235 */
236static void pgid_analyze(struct ccw_device *cdev, struct pgid **p, 236static void pgid_analyze(struct ccw_device *cdev, struct pgid **p,
237 int *mismatch, int *reserved, u8 *reset) 237 int *mismatch, u8 *reserved, u8 *reset)
238{ 238{
239 struct pgid *pgid = &cdev->private->pgid[0]; 239 struct pgid *pgid = &cdev->private->pgid[0];
240 struct pgid *first = NULL; 240 struct pgid *first = NULL;
@@ -248,7 +248,7 @@ static void pgid_analyze(struct ccw_device *cdev, struct pgid **p,
248 if ((cdev->private->pgid_valid_mask & lpm) == 0) 248 if ((cdev->private->pgid_valid_mask & lpm) == 0)
249 continue; 249 continue;
250 if (pgid->inf.ps.state2 == SNID_STATE2_RESVD_ELSE) 250 if (pgid->inf.ps.state2 == SNID_STATE2_RESVD_ELSE)
251 *reserved = 1; 251 *reserved |= lpm;
252 if (pgid_is_reset(pgid)) { 252 if (pgid_is_reset(pgid)) {
253 *reset |= lpm; 253 *reset |= lpm;
254 continue; 254 continue;
@@ -316,14 +316,14 @@ static void snid_done(struct ccw_device *cdev, int rc)
316 struct subchannel *sch = to_subchannel(cdev->dev.parent); 316 struct subchannel *sch = to_subchannel(cdev->dev.parent);
317 struct pgid *pgid; 317 struct pgid *pgid;
318 int mismatch = 0; 318 int mismatch = 0;
319 int reserved = 0; 319 u8 reserved = 0;
320 u8 reset = 0; 320 u8 reset = 0;
321 u8 donepm; 321 u8 donepm;
322 322
323 if (rc) 323 if (rc)
324 goto out; 324 goto out;
325 pgid_analyze(cdev, &pgid, &mismatch, &reserved, &reset); 325 pgid_analyze(cdev, &pgid, &mismatch, &reserved, &reset);
326 if (reserved) 326 if (reserved == cdev->private->pgid_valid_mask)
327 rc = -EUSERS; 327 rc = -EUSERS;
328 else if (mismatch) 328 else if (mismatch)
329 rc = -EOPNOTSUPP; 329 rc = -EOPNOTSUPP;
@@ -336,7 +336,7 @@ static void snid_done(struct ccw_device *cdev, int rc)
336 } 336 }
337out: 337out:
338 CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x " 338 CIO_MSG_EVENT(2, "snid: device 0.%x.%04x: rc=%d pvm=%02x vpm=%02x "
339 "todo=%02x mism=%d rsvd=%d reset=%02x\n", id->ssid, 339 "todo=%02x mism=%d rsvd=%02x reset=%02x\n", id->ssid,
340 id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm, 340 id->devno, rc, cdev->private->pgid_valid_mask, sch->vpm,
341 cdev->private->pgid_todo_mask, mismatch, reserved, reset); 341 cdev->private->pgid_todo_mask, mismatch, reserved, reset);
342 switch (rc) { 342 switch (rc) {
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index e06fa03ea1e4..1671d3461f29 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -129,7 +129,6 @@ static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
129 int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0; 129 int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0;
130 unsigned int ccq = 0; 130 unsigned int ccq = 0;
131 131
132 BUG_ON(!q->irq_ptr->sch_token);
133 qperf_inc(q, eqbs); 132 qperf_inc(q, eqbs);
134 133
135 if (!q->is_input_q) 134 if (!q->is_input_q)
@@ -147,7 +146,6 @@ again:
147 } 146 }
148 147
149 if (rc == 2) { 148 if (rc == 2) {
150 BUG_ON(tmp_count == count);
151 qperf_inc(q, eqbs_partial); 149 qperf_inc(q, eqbs_partial);
152 DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x", 150 DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x",
153 tmp_count); 151 tmp_count);
@@ -189,8 +187,6 @@ static int qdio_do_sqbs(struct qdio_q *q, unsigned char state, int start,
189 187
190 if (!count) 188 if (!count)
191 return 0; 189 return 0;
192
193 BUG_ON(!q->irq_ptr->sch_token);
194 qperf_inc(q, sqbs); 190 qperf_inc(q, sqbs);
195 191
196 if (!q->is_input_q) 192 if (!q->is_input_q)
@@ -199,7 +195,7 @@ again:
199 ccq = do_sqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count); 195 ccq = do_sqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count);
200 rc = qdio_check_ccq(q, ccq); 196 rc = qdio_check_ccq(q, ccq);
201 if (!rc) { 197 if (!rc) {
202 WARN_ON(tmp_count); 198 WARN_ON_ONCE(tmp_count);
203 return count - tmp_count; 199 return count - tmp_count;
204 } 200 }
205 201
@@ -224,9 +220,6 @@ static inline int get_buf_states(struct qdio_q *q, unsigned int bufnr,
224 unsigned char __state = 0; 220 unsigned char __state = 0;
225 int i; 221 int i;
226 222
227 BUG_ON(bufnr > QDIO_MAX_BUFFERS_MASK);
228 BUG_ON(count > QDIO_MAX_BUFFERS_PER_Q);
229
230 if (is_qebsm(q)) 223 if (is_qebsm(q))
231 return qdio_do_eqbs(q, state, bufnr, count, auto_ack); 224 return qdio_do_eqbs(q, state, bufnr, count, auto_ack);
232 225
@@ -258,9 +251,6 @@ static inline int set_buf_states(struct qdio_q *q, int bufnr,
258{ 251{
259 int i; 252 int i;
260 253
261 BUG_ON(bufnr > QDIO_MAX_BUFFERS_MASK);
262 BUG_ON(count > QDIO_MAX_BUFFERS_PER_Q);
263
264 if (is_qebsm(q)) 254 if (is_qebsm(q))
265 return qdio_do_sqbs(q, state, bufnr, count); 255 return qdio_do_sqbs(q, state, bufnr, count);
266 256
@@ -345,7 +335,6 @@ again:
345 335
346 /* hipersocket busy condition */ 336 /* hipersocket busy condition */
347 if (unlikely(*busy_bit)) { 337 if (unlikely(*busy_bit)) {
348 WARN_ON(queue_type(q) != QDIO_IQDIO_QFMT || cc != 2);
349 retries++; 338 retries++;
350 339
351 if (!start_time) { 340 if (!start_time) {
@@ -559,7 +548,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
559 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop"); 548 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in nop");
560 break; 549 break;
561 default: 550 default:
562 BUG(); 551 WARN_ON_ONCE(1);
563 } 552 }
564out: 553out:
565 return q->first_to_check; 554 return q->first_to_check;
@@ -678,12 +667,10 @@ static inline void qdio_handle_aobs(struct qdio_q *q, int start, int count)
678 if (aob == NULL) 667 if (aob == NULL)
679 continue; 668 continue;
680 669
681 BUG_ON(q->u.out.sbal_state == NULL);
682 q->u.out.sbal_state[b].flags |= 670 q->u.out.sbal_state[b].flags |=
683 QDIO_OUTBUF_STATE_FLAG_PENDING; 671 QDIO_OUTBUF_STATE_FLAG_PENDING;
684 q->u.out.aobs[b] = NULL; 672 q->u.out.aobs[b] = NULL;
685 } else if (state == SLSB_P_OUTPUT_EMPTY) { 673 } else if (state == SLSB_P_OUTPUT_EMPTY) {
686 BUG_ON(q->u.out.sbal_state == NULL);
687 q->u.out.sbal_state[b].aob = NULL; 674 q->u.out.sbal_state[b].aob = NULL;
688 } 675 }
689 b = next_buf(b); 676 b = next_buf(b);
@@ -703,12 +690,11 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
703 q->aobs[bufnr] = aob; 690 q->aobs[bufnr] = aob;
704 } 691 }
705 if (q->aobs[bufnr]) { 692 if (q->aobs[bufnr]) {
706 BUG_ON(q->sbal_state == NULL);
707 q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE; 693 q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE;
708 q->sbal_state[bufnr].aob = q->aobs[bufnr]; 694 q->sbal_state[bufnr].aob = q->aobs[bufnr];
709 q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user; 695 q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user;
710 phys_aob = virt_to_phys(q->aobs[bufnr]); 696 phys_aob = virt_to_phys(q->aobs[bufnr]);
711 BUG_ON(phys_aob & 0xFF); 697 WARN_ON_ONCE(phys_aob & 0xFF);
712 } 698 }
713 699
714out: 700out:
@@ -809,8 +795,6 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
809 goto out; 795 goto out;
810 796
811 switch (state) { 797 switch (state) {
812 case SLSB_P_OUTPUT_PENDING:
813 BUG();
814 case SLSB_P_OUTPUT_EMPTY: 798 case SLSB_P_OUTPUT_EMPTY:
815 /* the adapter got it */ 799 /* the adapter got it */
816 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, 800 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr,
@@ -840,7 +824,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
840 case SLSB_P_OUTPUT_HALTED: 824 case SLSB_P_OUTPUT_HALTED:
841 break; 825 break;
842 default: 826 default:
843 BUG(); 827 WARN_ON_ONCE(1);
844 } 828 }
845 829
846out: 830out:
@@ -912,7 +896,7 @@ retry:
912static void __qdio_outbound_processing(struct qdio_q *q) 896static void __qdio_outbound_processing(struct qdio_q *q)
913{ 897{
914 qperf_inc(q, tasklet_outbound); 898 qperf_inc(q, tasklet_outbound);
915 BUG_ON(atomic_read(&q->nr_buf_used) < 0); 899 WARN_ON_ONCE(atomic_read(&q->nr_buf_used) < 0);
916 900
917 if (qdio_outbound_q_moved(q)) 901 if (qdio_outbound_q_moved(q))
918 qdio_kick_handler(q); 902 qdio_kick_handler(q);
@@ -1138,16 +1122,10 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
1138 irq_ptr->perf_stat.qdio_int++; 1122 irq_ptr->perf_stat.qdio_int++;
1139 1123
1140 if (IS_ERR(irb)) { 1124 if (IS_ERR(irb)) {
1141 switch (PTR_ERR(irb)) { 1125 DBF_ERROR("%4x IO error", irq_ptr->schid.sch_no);
1142 case -EIO: 1126 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR);
1143 DBF_ERROR("%4x IO error", irq_ptr->schid.sch_no); 1127 wake_up(&cdev->private->wait_q);
1144 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_ERR); 1128 return;
1145 wake_up(&cdev->private->wait_q);
1146 return;
1147 default:
1148 WARN_ON(1);
1149 return;
1150 }
1151 } 1129 }
1152 qdio_irq_check_sense(irq_ptr, irb); 1130 qdio_irq_check_sense(irq_ptr, irb);
1153 cstat = irb->scsw.cmd.cstat; 1131 cstat = irb->scsw.cmd.cstat;
@@ -1173,7 +1151,7 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
1173 case QDIO_IRQ_STATE_STOPPED: 1151 case QDIO_IRQ_STATE_STOPPED:
1174 break; 1152 break;
1175 default: 1153 default:
1176 WARN_ON(1); 1154 WARN_ON_ONCE(1);
1177 } 1155 }
1178 wake_up(&cdev->private->wait_q); 1156 wake_up(&cdev->private->wait_q);
1179} 1157}
@@ -1227,7 +1205,7 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
1227 if (!irq_ptr) 1205 if (!irq_ptr)
1228 return -ENODEV; 1206 return -ENODEV;
1229 1207
1230 BUG_ON(irqs_disabled()); 1208 WARN_ON_ONCE(irqs_disabled());
1231 DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no); 1209 DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no);
1232 1210
1233 mutex_lock(&irq_ptr->setup_mutex); 1211 mutex_lock(&irq_ptr->setup_mutex);
@@ -1358,7 +1336,6 @@ int qdio_allocate(struct qdio_initialize *init_data)
1358 irq_ptr->qdr = (struct qdr *) get_zeroed_page(GFP_KERNEL | GFP_DMA); 1336 irq_ptr->qdr = (struct qdr *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
1359 if (!irq_ptr->qdr) 1337 if (!irq_ptr->qdr)
1360 goto out_rel; 1338 goto out_rel;
1361 WARN_ON((unsigned long)irq_ptr->qdr & 0xfff);
1362 1339
1363 if (qdio_allocate_qs(irq_ptr, init_data->no_input_qs, 1340 if (qdio_allocate_qs(irq_ptr, init_data->no_input_qs,
1364 init_data->no_output_qs)) 1341 init_data->no_output_qs))
@@ -1597,9 +1574,7 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags,
1597 1574
1598set: 1575set:
1599 count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count); 1576 count = set_buf_states(q, bufnr, SLSB_CU_INPUT_EMPTY, count);
1600
1601 used = atomic_add_return(count, &q->nr_buf_used) - count; 1577 used = atomic_add_return(count, &q->nr_buf_used) - count;
1602 BUG_ON(used + count > QDIO_MAX_BUFFERS_PER_Q);
1603 1578
1604 if (need_siga_in(q)) 1579 if (need_siga_in(q))
1605 return qdio_siga_input(q); 1580 return qdio_siga_input(q);
@@ -1624,7 +1599,6 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
1624 1599
1625 count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count); 1600 count = set_buf_states(q, bufnr, SLSB_CU_OUTPUT_PRIMED, count);
1626 used = atomic_add_return(count, &q->nr_buf_used); 1601 used = atomic_add_return(count, &q->nr_buf_used);
1627 BUG_ON(used > QDIO_MAX_BUFFERS_PER_Q);
1628 1602
1629 if (used == QDIO_MAX_BUFFERS_PER_Q) 1603 if (used == QDIO_MAX_BUFFERS_PER_Q)
1630 qperf_inc(q, outbound_queue_full); 1604 qperf_inc(q, outbound_queue_full);
@@ -1678,7 +1652,6 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
1678{ 1652{
1679 struct qdio_irq *irq_ptr; 1653 struct qdio_irq *irq_ptr;
1680 1654
1681
1682 if (bufnr >= QDIO_MAX_BUFFERS_PER_Q || count > QDIO_MAX_BUFFERS_PER_Q) 1655 if (bufnr >= QDIO_MAX_BUFFERS_PER_Q || count > QDIO_MAX_BUFFERS_PER_Q)
1683 return -EINVAL; 1656 return -EINVAL;
1684 1657
@@ -1721,8 +1694,6 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
1721 return -ENODEV; 1694 return -ENODEV;
1722 q = irq_ptr->input_qs[nr]; 1695 q = irq_ptr->input_qs[nr];
1723 1696
1724 WARN_ON(queue_irqs_enabled(q));
1725
1726 clear_nonshared_ind(irq_ptr); 1697 clear_nonshared_ind(irq_ptr);
1727 qdio_stop_polling(q); 1698 qdio_stop_polling(q);
1728 clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state); 1699 clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state);
@@ -1769,7 +1740,6 @@ int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr,
1769 if (!irq_ptr) 1740 if (!irq_ptr)
1770 return -ENODEV; 1741 return -ENODEV;
1771 q = irq_ptr->input_qs[nr]; 1742 q = irq_ptr->input_qs[nr];
1772 WARN_ON(queue_irqs_enabled(q));
1773 1743
1774 /* 1744 /*
1775 * Cannot rely on automatic sync after interrupt since queues may 1745 * Cannot rely on automatic sync after interrupt since queues may
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index 6c973db14983..16ecd35b8e51 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -140,10 +140,8 @@ static void setup_storage_lists(struct qdio_q *q, struct qdio_irq *irq_ptr,
140 q->sl = (struct sl *)((char *)q->slib + PAGE_SIZE / 2); 140 q->sl = (struct sl *)((char *)q->slib + PAGE_SIZE / 2);
141 141
142 /* fill in sbal */ 142 /* fill in sbal */
143 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++) { 143 for (j = 0; j < QDIO_MAX_BUFFERS_PER_Q; j++)
144 q->sbal[j] = *sbals_array++; 144 q->sbal[j] = *sbals_array++;
145 BUG_ON((unsigned long)q->sbal[j] & 0xff);
146 }
147 145
148 /* fill in slib */ 146 /* fill in slib */
149 if (i > 0) { 147 if (i > 0) {
@@ -434,9 +432,8 @@ int qdio_setup_irq(struct qdio_initialize *init_data)
434 irq_ptr->int_parm = init_data->int_parm; 432 irq_ptr->int_parm = init_data->int_parm;
435 irq_ptr->nr_input_qs = init_data->no_input_qs; 433 irq_ptr->nr_input_qs = init_data->no_input_qs;
436 irq_ptr->nr_output_qs = init_data->no_output_qs; 434 irq_ptr->nr_output_qs = init_data->no_output_qs;
437
438 irq_ptr->schid = ccw_device_get_subchannel_id(init_data->cdev);
439 irq_ptr->cdev = init_data->cdev; 435 irq_ptr->cdev = init_data->cdev;
436 ccw_device_get_schid(irq_ptr->cdev, &irq_ptr->schid);
440 setup_queues(irq_ptr, init_data); 437 setup_queues(irq_ptr, init_data);
441 438
442 setup_qib(irq_ptr, init_data); 439 setup_qib(irq_ptr, init_data);
@@ -483,7 +480,7 @@ void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
483 char s[80]; 480 char s[80];
484 481
485 snprintf(s, 80, "qdio: %s %s on SC %x using " 482 snprintf(s, 80, "qdio: %s %s on SC %x using "
486 "AI:%d QEBSM:%d PCI:%d TDD:%d SIGA:%s%s%s%s%s\n", 483 "AI:%d QEBSM:%d PRI:%d TDD:%d SIGA:%s%s%s%s%s\n",
487 dev_name(&cdev->dev), 484 dev_name(&cdev->dev),
488 (irq_ptr->qib.qfmt == QDIO_QETH_QFMT) ? "OSA" : 485 (irq_ptr->qib.qfmt == QDIO_QETH_QFMT) ? "OSA" :
489 ((irq_ptr->qib.qfmt == QDIO_ZFCP_QFMT) ? "ZFCP" : "HS"), 486 ((irq_ptr->qib.qfmt == QDIO_ZFCP_QFMT) ? "ZFCP" : "HS"),
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 2e060088fa87..bdb394b066fc 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -73,7 +73,6 @@ static void put_indicator(u32 *addr)
73void tiqdio_add_input_queues(struct qdio_irq *irq_ptr) 73void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
74{ 74{
75 mutex_lock(&tiq_list_lock); 75 mutex_lock(&tiq_list_lock);
76 BUG_ON(irq_ptr->nr_input_qs < 1);
77 list_add_rcu(&irq_ptr->input_qs[0]->entry, &tiq_list); 76 list_add_rcu(&irq_ptr->input_qs[0]->entry, &tiq_list);
78 mutex_unlock(&tiq_list_lock); 77 mutex_unlock(&tiq_list_lock);
79 xchg(irq_ptr->dsci, 1 << 7); 78 xchg(irq_ptr->dsci, 1 << 7);
@@ -83,7 +82,6 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
83{ 82{
84 struct qdio_q *q; 83 struct qdio_q *q;
85 84
86 BUG_ON(irq_ptr->nr_input_qs < 1);
87 q = irq_ptr->input_qs[0]; 85 q = irq_ptr->input_qs[0];
88 /* if establish triggered an error */ 86 /* if establish triggered an error */
89 if (!q || !q->entry.prev || !q->entry.next) 87 if (!q || !q->entry.prev || !q->entry.next)
diff --git a/drivers/s390/crypto/zcrypt_msgtype50.c b/drivers/s390/crypto/zcrypt_msgtype50.c
index 035b6dc31b71..7c522f338bda 100644
--- a/drivers/s390/crypto/zcrypt_msgtype50.c
+++ b/drivers/s390/crypto/zcrypt_msgtype50.c
@@ -241,84 +241,70 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_device *zdev,
241 struct ap_message *ap_msg, 241 struct ap_message *ap_msg,
242 struct ica_rsa_modexpo_crt *crt) 242 struct ica_rsa_modexpo_crt *crt)
243{ 243{
244 int mod_len, short_len, long_len, long_offset, limit; 244 int mod_len, short_len;
245 unsigned char *p, *q, *dp, *dq, *u, *inp; 245 unsigned char *p, *q, *dp, *dq, *u, *inp;
246 246
247 mod_len = crt->inputdatalength; 247 mod_len = crt->inputdatalength;
248 short_len = mod_len / 2; 248 short_len = mod_len / 2;
249 long_len = mod_len / 2 + 8;
250 249
251 /* 250 /*
252 * CEX2A cannot handle p, dp, or U > 128 bytes. 251 * CEX2A and CEX3A w/o FW update can handle requests up to
253 * If we have one of these, we need to do extra checking. 252 * 256 byte modulus (2k keys).
254 * For CEX3A the limit is 256 bytes. 253 * CEX3A with FW update and CEX4A cards are able to handle
254 * 512 byte modulus (4k keys).
255 */ 255 */
256 if (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE) 256 if (mod_len <= 128) { /* up to 1024 bit key size */
257 limit = 256;
258 else
259 limit = 128;
260
261 if (long_len > limit) {
262 /*
263 * zcrypt_rsa_crt already checked for the leading
264 * zeroes of np_prime, bp_key and u_mult_inc.
265 */
266 long_offset = long_len - limit;
267 long_len = limit;
268 } else
269 long_offset = 0;
270
271 /*
272 * Instead of doing extra work for p, dp, U > 64 bytes, we'll just use
273 * the larger message structure.
274 */
275 if (long_len <= 64) {
276 struct type50_crb1_msg *crb1 = ap_msg->message; 257 struct type50_crb1_msg *crb1 = ap_msg->message;
277 memset(crb1, 0, sizeof(*crb1)); 258 memset(crb1, 0, sizeof(*crb1));
278 ap_msg->length = sizeof(*crb1); 259 ap_msg->length = sizeof(*crb1);
279 crb1->header.msg_type_code = TYPE50_TYPE_CODE; 260 crb1->header.msg_type_code = TYPE50_TYPE_CODE;
280 crb1->header.msg_len = sizeof(*crb1); 261 crb1->header.msg_len = sizeof(*crb1);
281 crb1->keyblock_type = TYPE50_CRB1_FMT; 262 crb1->keyblock_type = TYPE50_CRB1_FMT;
282 p = crb1->p + sizeof(crb1->p) - long_len; 263 p = crb1->p + sizeof(crb1->p) - short_len;
283 q = crb1->q + sizeof(crb1->q) - short_len; 264 q = crb1->q + sizeof(crb1->q) - short_len;
284 dp = crb1->dp + sizeof(crb1->dp) - long_len; 265 dp = crb1->dp + sizeof(crb1->dp) - short_len;
285 dq = crb1->dq + sizeof(crb1->dq) - short_len; 266 dq = crb1->dq + sizeof(crb1->dq) - short_len;
286 u = crb1->u + sizeof(crb1->u) - long_len; 267 u = crb1->u + sizeof(crb1->u) - short_len;
287 inp = crb1->message + sizeof(crb1->message) - mod_len; 268 inp = crb1->message + sizeof(crb1->message) - mod_len;
288 } else if (long_len <= 128) { 269 } else if (mod_len <= 256) { /* up to 2048 bit key size */
289 struct type50_crb2_msg *crb2 = ap_msg->message; 270 struct type50_crb2_msg *crb2 = ap_msg->message;
290 memset(crb2, 0, sizeof(*crb2)); 271 memset(crb2, 0, sizeof(*crb2));
291 ap_msg->length = sizeof(*crb2); 272 ap_msg->length = sizeof(*crb2);
292 crb2->header.msg_type_code = TYPE50_TYPE_CODE; 273 crb2->header.msg_type_code = TYPE50_TYPE_CODE;
293 crb2->header.msg_len = sizeof(*crb2); 274 crb2->header.msg_len = sizeof(*crb2);
294 crb2->keyblock_type = TYPE50_CRB2_FMT; 275 crb2->keyblock_type = TYPE50_CRB2_FMT;
295 p = crb2->p + sizeof(crb2->p) - long_len; 276 p = crb2->p + sizeof(crb2->p) - short_len;
296 q = crb2->q + sizeof(crb2->q) - short_len; 277 q = crb2->q + sizeof(crb2->q) - short_len;
297 dp = crb2->dp + sizeof(crb2->dp) - long_len; 278 dp = crb2->dp + sizeof(crb2->dp) - short_len;
298 dq = crb2->dq + sizeof(crb2->dq) - short_len; 279 dq = crb2->dq + sizeof(crb2->dq) - short_len;
299 u = crb2->u + sizeof(crb2->u) - long_len; 280 u = crb2->u + sizeof(crb2->u) - short_len;
300 inp = crb2->message + sizeof(crb2->message) - mod_len; 281 inp = crb2->message + sizeof(crb2->message) - mod_len;
301 } else { 282 } else if ((mod_len <= 512) && /* up to 4096 bit key size */
302 /* long_len >= 256 */ 283 (zdev->max_mod_size == CEX3A_MAX_MOD_SIZE)) { /* >= CEX3A */
303 struct type50_crb3_msg *crb3 = ap_msg->message; 284 struct type50_crb3_msg *crb3 = ap_msg->message;
304 memset(crb3, 0, sizeof(*crb3)); 285 memset(crb3, 0, sizeof(*crb3));
305 ap_msg->length = sizeof(*crb3); 286 ap_msg->length = sizeof(*crb3);
306 crb3->header.msg_type_code = TYPE50_TYPE_CODE; 287 crb3->header.msg_type_code = TYPE50_TYPE_CODE;
307 crb3->header.msg_len = sizeof(*crb3); 288 crb3->header.msg_len = sizeof(*crb3);
308 crb3->keyblock_type = TYPE50_CRB3_FMT; 289 crb3->keyblock_type = TYPE50_CRB3_FMT;
309 p = crb3->p + sizeof(crb3->p) - long_len; 290 p = crb3->p + sizeof(crb3->p) - short_len;
310 q = crb3->q + sizeof(crb3->q) - short_len; 291 q = crb3->q + sizeof(crb3->q) - short_len;
311 dp = crb3->dp + sizeof(crb3->dp) - long_len; 292 dp = crb3->dp + sizeof(crb3->dp) - short_len;
312 dq = crb3->dq + sizeof(crb3->dq) - short_len; 293 dq = crb3->dq + sizeof(crb3->dq) - short_len;
313 u = crb3->u + sizeof(crb3->u) - long_len; 294 u = crb3->u + sizeof(crb3->u) - short_len;
314 inp = crb3->message + sizeof(crb3->message) - mod_len; 295 inp = crb3->message + sizeof(crb3->message) - mod_len;
315 } 296 } else
297 return -EINVAL;
316 298
317 if (copy_from_user(p, crt->np_prime + long_offset, long_len) || 299 /*
300 * correct the offset of p, bp and mult_inv according zcrypt.h
301 * block size right aligned (skip the first byte)
302 */
303 if (copy_from_user(p, crt->np_prime + MSGTYPE_ADJUSTMENT, short_len) ||
318 copy_from_user(q, crt->nq_prime, short_len) || 304 copy_from_user(q, crt->nq_prime, short_len) ||
319 copy_from_user(dp, crt->bp_key + long_offset, long_len) || 305 copy_from_user(dp, crt->bp_key + MSGTYPE_ADJUSTMENT, short_len) ||
320 copy_from_user(dq, crt->bq_key, short_len) || 306 copy_from_user(dq, crt->bq_key, short_len) ||
321 copy_from_user(u, crt->u_mult_inv + long_offset, long_len) || 307 copy_from_user(u, crt->u_mult_inv + MSGTYPE_ADJUSTMENT, short_len) ||
322 copy_from_user(inp, crt->inputdata, mod_len)) 308 copy_from_user(inp, crt->inputdata, mod_len))
323 return -EFAULT; 309 return -EFAULT;
324 310
diff --git a/drivers/s390/crypto/zcrypt_msgtype50.h b/drivers/s390/crypto/zcrypt_msgtype50.h
index e56dc72c7733..0a66e4aeeb50 100644
--- a/drivers/s390/crypto/zcrypt_msgtype50.h
+++ b/drivers/s390/crypto/zcrypt_msgtype50.h
@@ -33,6 +33,8 @@
33#define MSGTYPE50_CRB2_MAX_MSG_SIZE 0x390 /*sizeof(struct type50_crb2_msg)*/ 33#define MSGTYPE50_CRB2_MAX_MSG_SIZE 0x390 /*sizeof(struct type50_crb2_msg)*/
34#define MSGTYPE50_CRB3_MAX_MSG_SIZE 0x710 /*sizeof(struct type50_crb3_msg)*/ 34#define MSGTYPE50_CRB3_MAX_MSG_SIZE 0x710 /*sizeof(struct type50_crb3_msg)*/
35 35
36#define MSGTYPE_ADJUSTMENT 0x08 /*type04 extension (not needed in type50)*/
37
36int zcrypt_msgtype50_init(void); 38int zcrypt_msgtype50_init(void);
37void zcrypt_msgtype50_exit(void); 39void zcrypt_msgtype50_exit(void);
38 40