diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 17:20:19 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-13 17:20:19 -0500 |
commit | c7708fac5a878d6e0f2de0aa19f9749cff4f707f (patch) | |
tree | 21a59cbe503ca526697f7d0bce5e0e30980bcbc0 /drivers/s390 | |
parent | 3127f23f013eabe9b58132c05061684c49146ba3 (diff) | |
parent | 6726a807c38d7fd09bc23a0adc738efec6ff9492 (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.c | 97 | ||||
-rw-r--r-- | drivers/s390/block/dasd_devmap.c | 34 | ||||
-rw-r--r-- | drivers/s390/block/dasd_eckd.c | 92 | ||||
-rw-r--r-- | drivers/s390/block/dasd_fba.c | 23 | ||||
-rw-r--r-- | drivers/s390/block/dasd_int.h | 2 | ||||
-rw-r--r-- | drivers/s390/block/dasd_ioctl.c | 11 | ||||
-rw-r--r-- | drivers/s390/char/sclp.h | 3 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cmd.c | 81 | ||||
-rw-r--r-- | drivers/s390/cio/ccwgroup.c | 26 | ||||
-rw-r--r-- | drivers/s390/cio/chsc.c | 156 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 11 | ||||
-rw-r--r-- | drivers/s390/cio/device.h | 2 | ||||
-rw-r--r-- | drivers/s390/cio/device_ops.c | 17 | ||||
-rw-r--r-- | drivers/s390/cio/device_pgid.c | 10 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_main.c | 52 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_setup.c | 9 | ||||
-rw-r--r-- | drivers/s390/cio/qdio_thinint.c | 2 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_msgtype50.c | 68 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_msgtype50.h | 2 |
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 | ||
352 | static inline | ||
353 | int _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 | |||
3238 | interrupted: | ||
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 | ||
3175 | int dasd_generic_last_path_gone(struct dasd_device *device) | 3247 | int dasd_generic_last_path_gone(struct dasd_device *device) |
@@ -3489,15 +3561,6 @@ char *dasd_get_sense(struct irb *irb) | |||
3489 | } | 3561 | } |
3490 | EXPORT_SYMBOL_GPL(dasd_get_sense); | 3562 | EXPORT_SYMBOL_GPL(dasd_get_sense); |
3491 | 3563 | ||
3492 | static 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 | |||
3501 | void dasd_generic_shutdown(struct ccw_device *cdev) | 3564 | void 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 | ||
954 | static ssize_t | 954 | static ssize_t |
955 | dasd_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 | |||
981 | out: | ||
982 | return rc ? rc : count; | ||
983 | } | ||
984 | |||
985 | static DEVICE_ATTR(safe_offline, 0200, NULL, dasd_safe_offline_store); | ||
986 | |||
987 | static ssize_t | ||
955 | dasd_discipline_show(struct device *dev, struct device_attribute *attr, | 988 | dasd_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 | ||
1148 | static int verify_fcx_max_data(struct dasd_device *device, __u8 lpm) | 1150 | static 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 | ||
521 | void dasd_put_device_wake(struct dasd_device *); | 523 | void 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 | ||
108 | struct gds_subvector { | 109 | struct 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 | ||
401 | static int sclp_assign_storage(u16 rn) | 403 | static 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; |
412 | out: | ||
413 | return rc; | ||
414 | } | 414 | } |
415 | 415 | ||
416 | static int sclp_unassign_storage(u16 rn) | 416 | static 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 | |||
712 | struct 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 | |||
720 | static 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 | } | ||
748 | out: | ||
749 | free_page((unsigned long) sccb); | ||
750 | return rc; | ||
751 | } | ||
752 | |||
753 | int sclp_pci_configure(u32 fid) | ||
754 | { | ||
755 | return do_pci_configure(SCLP_CMDW_CONFIGURE_PCI, fid); | ||
756 | } | ||
757 | EXPORT_SYMBOL(sclp_pci_configure); | ||
758 | |||
759 | int sclp_pci_deconfigure(u32 fid) | ||
760 | { | ||
761 | return do_pci_configure(SCLP_CMDW_DECONFIGURE_PCI, fid); | ||
762 | } | ||
763 | EXPORT_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 | ||
68 | static 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 | */ | ||
76 | int 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 | } |
95 | EXPORT_SYMBOL(ccwgroup_set_online); | ||
87 | 96 | ||
88 | static 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 | */ | ||
105 | int 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 | } |
124 | EXPORT_SYMBOL(ccwgroup_set_offline); | ||
107 | 125 | ||
108 | static ssize_t ccwgroup_online_store(struct device *dev, | 126 | static 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 | ||
263 | struct chsc_sei_area { | 264 | struct 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; | |
282 | static void chsc_process_sei_link_incident(struct chsc_sei_area *sei_area) | 276 | |
277 | struct 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 | |||
289 | struct 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 | |||
302 | static 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 | ||
301 | static void chsc_process_sei_res_acc(struct chsc_sei_area *sei_area) | 321 | static 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 | ||
333 | static void chsc_process_sei_chp_avail(struct chsc_sei_area *sei_area) | 353 | static 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 | ||
369 | static void chsc_process_sei_chp_config(struct chsc_sei_area *sei_area) | 389 | static 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 | ||
401 | static void chsc_process_sei_scm_change(struct chsc_sei_area *sei_area) | 421 | static 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 | ||
415 | static void chsc_process_sei(struct chsc_sei_area *sei_area) | 435 | static 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 | |||
453 | static 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 | ||
479 | static 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 | |||
446 | static void chsc_process_crw(struct crw *crw0, struct crw *crw1, int overflow) | 521 | static 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 | ||
483 | void chsc_chp_online(struct chp_id chpid) | 551 | void 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. */ | ||
2040 | struct subchannel_id | ||
2041 | ccw_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 | |||
2049 | static void ccw_device_todo(struct work_struct *work) | 2039 | static 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); | |||
2138 | EXPORT_SYMBOL(ccw_driver_register); | 2128 | EXPORT_SYMBOL(ccw_driver_register); |
2139 | EXPORT_SYMBOL(ccw_driver_unregister); | 2129 | EXPORT_SYMBOL(ccw_driver_unregister); |
2140 | EXPORT_SYMBOL(get_ccwdev_by_busid); | 2130 | EXPORT_SYMBOL(get_ccwdev_by_busid); |
2141 | EXPORT_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); | |||
142 | void ccw_device_set_disconnected(struct ccw_device *cdev); | 142 | void ccw_device_set_disconnected(struct ccw_device *cdev); |
143 | void ccw_device_set_notoper(struct ccw_device *cdev); | 143 | void ccw_device_set_notoper(struct ccw_device *cdev); |
144 | 144 | ||
145 | /* qdio needs this. */ | ||
146 | void ccw_device_set_timeout(struct ccw_device *, int); | 145 | void ccw_device_set_timeout(struct ccw_device *, int); |
147 | extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); | ||
148 | 146 | ||
149 | /* Channel measurement facility related */ | 147 | /* Channel measurement facility related */ |
150 | void retry_set_schib(struct ccw_device *cdev); | 148 | void 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 | } |
756 | EXPORT_SYMBOL(ccw_device_tm_intrg); | 756 | EXPORT_SYMBOL(ccw_device_tm_intrg); |
757 | 757 | ||
758 | // FIXME: these have to go: | 758 | /** |
759 | 759 | * ccw_device_get_schid - obtain a subchannel id | |
760 | int | 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 | */ | ||
763 | void 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 | } | ||
769 | EXPORT_SYMBOL_GPL(ccw_device_get_schid); | ||
766 | 770 | ||
767 | MODULE_LICENSE("GPL"); | 771 | MODULE_LICENSE("GPL"); |
768 | EXPORT_SYMBOL(ccw_device_set_options_mask); | 772 | EXPORT_SYMBOL(ccw_device_set_options_mask); |
@@ -777,5 +781,4 @@ EXPORT_SYMBOL(ccw_device_start_timeout_key); | |||
777 | EXPORT_SYMBOL(ccw_device_start_key); | 781 | EXPORT_SYMBOL(ccw_device_start_key); |
778 | EXPORT_SYMBOL(ccw_device_get_ciw); | 782 | EXPORT_SYMBOL(ccw_device_get_ciw); |
779 | EXPORT_SYMBOL(ccw_device_get_path_mask); | 783 | EXPORT_SYMBOL(ccw_device_get_path_mask); |
780 | EXPORT_SYMBOL(_ccw_device_get_subchannel_number); | ||
781 | EXPORT_SYMBOL_GPL(ccw_device_get_chp_desc); | 784 | EXPORT_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 | */ |
236 | static void pgid_analyze(struct ccw_device *cdev, struct pgid **p, | 236 | static 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 | } |
337 | out: | 337 | out: |
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 | } |
564 | out: | 553 | out: |
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 | ||
714 | out: | 700 | out: |
@@ -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 | ||
846 | out: | 830 | out: |
@@ -912,7 +896,7 @@ retry: | |||
912 | static void __qdio_outbound_processing(struct qdio_q *q) | 896 | static 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 | ||
1598 | set: | 1575 | set: |
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) | |||
73 | void tiqdio_add_input_queues(struct qdio_irq *irq_ptr) | 73 | void 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 | |||
36 | int zcrypt_msgtype50_init(void); | 38 | int zcrypt_msgtype50_init(void); |
37 | void zcrypt_msgtype50_exit(void); | 39 | void zcrypt_msgtype50_exit(void); |
38 | 40 | ||