summaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dcssblk.c52
-rw-r--r--drivers/s390/cio/css.c7
-rw-r--r--drivers/s390/cio/idset.c26
-rw-r--r--drivers/s390/cio/idset.h3
-rw-r--r--drivers/s390/crypto/zcrypt_pcixcc.c1
-rw-r--r--drivers/s390/kvm/kvm_virtio.c5
-rw-r--r--drivers/s390/net/qeth_l2_main.c11
-rw-r--r--drivers/s390/net/qeth_l3_main.c11
-rw-r--r--drivers/s390/net/smsgiucv.c2
9 files changed, 62 insertions, 56 deletions
diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c
index a5a55da2a1a..b6ad0de0793 100644
--- a/drivers/s390/block/dcssblk.c
+++ b/drivers/s390/block/dcssblk.c
@@ -69,23 +69,9 @@ static ssize_t dcssblk_add_store(struct device * dev, struct device_attribute *a
size_t count);
static ssize_t dcssblk_remove_store(struct device * dev, struct device_attribute *attr, const char * buf,
size_t count);
-static ssize_t dcssblk_save_store(struct device * dev, struct device_attribute *attr, const char * buf,
- size_t count);
-static ssize_t dcssblk_save_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t dcssblk_shared_store(struct device * dev, struct device_attribute *attr, const char * buf,
- size_t count);
-static ssize_t dcssblk_shared_show(struct device *dev, struct device_attribute *attr, char *buf);
-static ssize_t dcssblk_seglist_show(struct device *dev,
- struct device_attribute *attr,
- char *buf);
static DEVICE_ATTR(add, S_IWUSR, NULL, dcssblk_add_store);
static DEVICE_ATTR(remove, S_IWUSR, NULL, dcssblk_remove_store);
-static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
- dcssblk_save_store);
-static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
- dcssblk_shared_store);
-static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
static struct device *dcssblk_root_dev;
@@ -416,6 +402,8 @@ out:
up_write(&dcssblk_devices_sem);
return rc;
}
+static DEVICE_ATTR(shared, S_IWUSR | S_IRUSR, dcssblk_shared_show,
+ dcssblk_shared_store);
/*
* device attribute for save operation on current copy
@@ -476,6 +464,8 @@ dcssblk_save_store(struct device *dev, struct device_attribute *attr, const char
up_write(&dcssblk_devices_sem);
return count;
}
+static DEVICE_ATTR(save, S_IWUSR | S_IRUSR, dcssblk_save_show,
+ dcssblk_save_store);
/*
* device attribute for showing all segments in a device
@@ -502,6 +492,21 @@ dcssblk_seglist_show(struct device *dev, struct device_attribute *attr,
up_read(&dcssblk_devices_sem);
return i;
}
+static DEVICE_ATTR(seglist, S_IRUSR, dcssblk_seglist_show, NULL);
+
+static struct attribute *dcssblk_dev_attrs[] = {
+ &dev_attr_shared.attr,
+ &dev_attr_save.attr,
+ &dev_attr_seglist.attr,
+ NULL,
+};
+static struct attribute_group dcssblk_dev_attr_group = {
+ .attrs = dcssblk_dev_attrs,
+};
+static const struct attribute_group *dcssblk_dev_attr_groups[] = {
+ &dcssblk_dev_attr_group,
+ NULL,
+};
/*
* device attribute for adding devices
@@ -590,6 +595,7 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
dev_set_name(&dev_info->dev, dev_info->segment_name);
dev_info->dev.release = dcssblk_release_segment;
+ dev_info->dev.groups = dcssblk_dev_attr_groups;
INIT_LIST_HEAD(&dev_info->lh);
dev_info->gd = alloc_disk(DCSSBLK_MINORS_PER_DISK);
if (dev_info->gd == NULL) {
@@ -637,21 +643,10 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
* register the device
*/
rc = device_register(&dev_info->dev);
- if (rc) {
- module_put(THIS_MODULE);
- goto dev_list_del;
- }
- get_device(&dev_info->dev);
- rc = device_create_file(&dev_info->dev, &dev_attr_shared);
- if (rc)
- goto unregister_dev;
- rc = device_create_file(&dev_info->dev, &dev_attr_save);
- if (rc)
- goto unregister_dev;
- rc = device_create_file(&dev_info->dev, &dev_attr_seglist);
if (rc)
- goto unregister_dev;
+ goto put_dev;
+ get_device(&dev_info->dev);
add_disk(dev_info->gd);
switch (dev_info->segment_type) {
@@ -668,12 +663,11 @@ dcssblk_add_store(struct device *dev, struct device_attribute *attr, const char
rc = count;
goto out;
-unregister_dev:
+put_dev:
list_del(&dev_info->lh);
blk_cleanup_queue(dev_info->dcssblk_queue);
dev_info->gd->queue = NULL;
put_disk(dev_info->gd);
- device_unregister(&dev_info->dev);
list_for_each_entry(seg_info, &dev_info->seg_list, lh) {
segment_unload(seg_info->segment_name);
}
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index b4d572f65f0..fd00afd8b85 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -377,7 +377,11 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow)
/* Will be done on the slow path. */
return -EAGAIN;
}
- if (stsch_err(schid, &schib) || !css_sch_is_valid(&schib)) {
+ if (stsch_err(schid, &schib)) {
+ /* Subchannel is not provided. */
+ return -ENXIO;
+ }
+ if (!css_sch_is_valid(&schib)) {
/* Unusable - ignore. */
return 0;
}
@@ -536,6 +540,7 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data)
case -ENOMEM:
case -EIO:
/* These should abort looping */
+ idset_sch_del_subseq(slow_subchannel_set, schid);
break;
default:
rc = 0;
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c
index e6d5f8c4952..199bc679117 100644
--- a/drivers/s390/cio/idset.c
+++ b/drivers/s390/cio/idset.c
@@ -1,9 +1,10 @@
/*
- * Copyright IBM Corp. 2007
+ * Copyright IBM Corp. 2007, 2012
* Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
*/
#include <linux/vmalloc.h>
+#include <linux/bitmap.h>
#include <linux/bitops.h>
#include "idset.h"
#include "css.h"
@@ -89,6 +90,14 @@ void idset_sch_del(struct idset *set, struct subchannel_id schid)
idset_del(set, schid.ssid, schid.sch_no);
}
+/* Clear ids starting from @schid up to end of subchannel set. */
+void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid)
+{
+ int pos = schid.ssid * set->num_id + schid.sch_no;
+
+ bitmap_clear(set->bitmap, pos, set->num_id - schid.sch_no);
+}
+
int idset_sch_contains(struct idset *set, struct subchannel_id schid)
{
return idset_contains(set, schid.ssid, schid.sch_no);
@@ -111,20 +120,13 @@ int idset_sch_get_first(struct idset *set, struct subchannel_id *schid)
int idset_is_empty(struct idset *set)
{
- int bitnum;
-
- bitnum = find_first_bit(set->bitmap, set->num_ssid * set->num_id);
- if (bitnum >= set->num_ssid * set->num_id)
- return 1;
- return 0;
+ return bitmap_empty(set->bitmap, set->num_ssid * set->num_id);
}
void idset_add_set(struct idset *to, struct idset *from)
{
- unsigned long i, len;
+ int len = min(__BITOPS_WORDS(to->num_ssid * to->num_id),
+ __BITOPS_WORDS(from->num_ssid * from->num_id));
- len = min(__BITOPS_WORDS(to->num_ssid * to->num_id),
- __BITOPS_WORDS(from->num_ssid * from->num_id));
- for (i = 0; i < len ; i++)
- to->bitmap[i] |= from->bitmap[i];
+ bitmap_or(to->bitmap, to->bitmap, from->bitmap, len);
}
diff --git a/drivers/s390/cio/idset.h b/drivers/s390/cio/idset.h
index 3d943f03591..06d3bc01bb0 100644
--- a/drivers/s390/cio/idset.h
+++ b/drivers/s390/cio/idset.h
@@ -1,5 +1,5 @@
/*
- * Copyright IBM Corp. 2007
+ * Copyright IBM Corp. 2007, 2012
* Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
*/
@@ -17,6 +17,7 @@ void idset_fill(struct idset *set);
struct idset *idset_sch_new(void);
void idset_sch_add(struct idset *set, struct subchannel_id id);
void idset_sch_del(struct idset *set, struct subchannel_id id);
+void idset_sch_del_subseq(struct idset *set, struct subchannel_id schid);
int idset_sch_contains(struct idset *set, struct subchannel_id id);
int idset_sch_get_first(struct idset *set, struct subchannel_id *id);
int idset_is_empty(struct idset *set);
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c
index c7275e303a0..899ffa19f5e 100644
--- a/drivers/s390/crypto/zcrypt_pcixcc.c
+++ b/drivers/s390/crypto/zcrypt_pcixcc.c
@@ -39,7 +39,6 @@
#include "zcrypt_msgtype6.h"
#include "zcrypt_pcixcc.h"
#include "zcrypt_cca_key.h"
-#include "zcrypt_msgtype6.h"
#define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */
#define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index 47cccd52aae..7dabef624da 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -190,6 +190,9 @@ static struct virtqueue *kvm_find_vq(struct virtio_device *vdev,
if (index >= kdev->desc->num_vq)
return ERR_PTR(-ENOENT);
+ if (!name)
+ return NULL;
+
config = kvm_vq_config(kdev->desc)+index;
err = vmem_add_mapping(config->address,
@@ -198,7 +201,7 @@ static struct virtqueue *kvm_find_vq(struct virtio_device *vdev,
if (err)
goto out;
- vq = vring_new_virtqueue(config->num, KVM_S390_VIRTIO_RING_ALIGN,
+ vq = vring_new_virtqueue(index, config->num, KVM_S390_VIRTIO_RING_ALIGN,
vdev, true, (void *) config->address,
kvm_notify, callback, name);
if (!vq) {
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 2db409330c2..e67e0258aec 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1141,11 +1141,12 @@ static int qeth_l2_recover(void *ptr)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
else {
- rtnl_lock();
- dev_close(card->dev);
- rtnl_unlock();
- dev_warn(&card->gdev->dev, "The qeth device driver "
- "failed to recover an error on the device\n");
+ if (rtnl_trylock()) {
+ dev_close(card->dev);
+ rtnl_unlock();
+ dev_warn(&card->gdev->dev, "The qeth device driver "
+ "failed to recover an error on the device\n");
+ }
}
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 4cd310cb5bd..5ba39065849 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -3510,11 +3510,12 @@ static int qeth_l3_recover(void *ptr)
dev_info(&card->gdev->dev,
"Device successfully recovered!\n");
else {
- rtnl_lock();
- dev_close(card->dev);
- rtnl_unlock();
- dev_warn(&card->gdev->dev, "The qeth device driver "
- "failed to recover an error on the device\n");
+ if (rtnl_trylock()) {
+ dev_close(card->dev);
+ rtnl_unlock();
+ dev_warn(&card->gdev->dev, "The qeth device driver "
+ "failed to recover an error on the device\n");
+ }
}
qeth_clear_thread_start_bit(card, QETH_RECOVER_THREAD);
qeth_clear_thread_running_bit(card, QETH_RECOVER_THREAD);
diff --git a/drivers/s390/net/smsgiucv.c b/drivers/s390/net/smsgiucv.c
index 207b7d74244..d8f990b6b33 100644
--- a/drivers/s390/net/smsgiucv.c
+++ b/drivers/s390/net/smsgiucv.c
@@ -157,7 +157,7 @@ static int smsg_pm_restore_thaw(struct device *dev)
#ifdef CONFIG_PM_DEBUG
printk(KERN_WARNING "smsg_pm_restore_thaw\n");
#endif
- if (smsg_path && iucv_path_connected) {
+ if (smsg_path && !iucv_path_connected) {
memset(smsg_path, 0, sizeof(*smsg_path));
smsg_path->msglim = 255;
smsg_path->flags = 0;