summaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/block/dasd.c11
-rw-r--r--drivers/s390/block/dasd_eckd.c2
-rw-r--r--drivers/s390/block/dasd_genhd.c1
-rw-r--r--drivers/s390/block/scm_blk.c30
-rw-r--r--drivers/s390/block/scm_blk.h2
-rw-r--r--drivers/s390/block/scm_blk_cluster.c2
-rw-r--r--drivers/s390/char/Makefile3
-rw-r--r--drivers/s390/char/fs3270.c1
-rw-r--r--drivers/s390/char/monwriter.c2
-rw-r--r--drivers/s390/char/raw3270.c4
-rw-r--r--drivers/s390/char/sclp.h5
-rw-r--r--drivers/s390/char/sclp_cmd.c180
-rw-r--r--drivers/s390/char/sclp_early.c263
-rw-r--r--drivers/s390/char/sclp_sdias.c78
-rw-r--r--drivers/s390/char/sclp_sdias.h46
-rw-r--r--drivers/s390/char/tty3270.c2
-rw-r--r--drivers/s390/char/zcore.c42
-rw-r--r--drivers/s390/cio/airq.c19
-rw-r--r--drivers/s390/cio/eadm_sch.c39
-rw-r--r--drivers/s390/cio/eadm_sch.h4
-rw-r--r--drivers/s390/cio/qdio_debug.h8
-rw-r--r--drivers/s390/cio/qdio_main.c2
-rw-r--r--drivers/s390/cio/scm.c45
-rw-r--r--drivers/s390/crypto/zcrypt_debug.h12
-rw-r--r--drivers/s390/kvm/kvm_virtio.c8
-rw-r--r--drivers/s390/kvm/virtio_ccw.c5
-rw-r--r--drivers/s390/net/claw.h8
-rw-r--r--drivers/s390/net/ctcm_dbug.c2
-rw-r--r--drivers/s390/net/lcs.h8
-rw-r--r--drivers/s390/net/netiucv.c8
-rw-r--r--drivers/s390/net/qeth_core_main.c8
-rw-r--r--drivers/s390/scsi/zfcp_dbf.c6
-rw-r--r--drivers/s390/scsi/zfcp_dbf.h4
33 files changed, 457 insertions, 403 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 451bf99582ff..f302efa937ef 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -698,10 +698,11 @@ static void dasd_profile_start(struct dasd_block *block,
}
spin_lock(&block->profile.lock);
- if (block->profile.data)
+ if (block->profile.data) {
block->profile.data->dasd_io_nr_req[counter]++;
if (rq_data_dir(req) == READ)
block->profile.data->dasd_read_nr_req[counter]++;
+ }
spin_unlock(&block->profile.lock);
/*
@@ -2978,12 +2979,12 @@ static int dasd_alloc_queue(struct dasd_block *block)
elevator_exit(block->request_queue->elevator);
block->request_queue->elevator = NULL;
+ mutex_lock(&block->request_queue->sysfs_lock);
rc = elevator_init(block->request_queue, "deadline");
- if (rc) {
+ if (rc)
blk_cleanup_queue(block->request_queue);
- return rc;
- }
- return 0;
+ mutex_unlock(&block->request_queue->sysfs_lock);
+ return rc;
}
/*
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index cee7e2708a1f..95e45782692f 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -3224,6 +3224,8 @@ static struct dasd_ccw_req *dasd_eckd_build_cp(struct dasd_device *startdev,
fcx_multitrack = private->features.feature[40] & 0x20;
data_size = blk_rq_bytes(req);
+ if (data_size % blksize)
+ return ERR_PTR(-EINVAL);
/* tpm write request add CBC data on each track boundary */
if (rq_data_dir(req) == WRITE)
data_size += (last_trk - first_trk) * 4;
diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c
index f64921756ad6..f224d59c4b6b 100644
--- a/drivers/s390/block/dasd_genhd.c
+++ b/drivers/s390/block/dasd_genhd.c
@@ -87,7 +87,6 @@ void dasd_gendisk_free(struct dasd_block *block)
{
if (block->gdp) {
del_gendisk(block->gdp);
- block->gdp->queue = NULL;
block->gdp->private_data = NULL;
put_disk(block->gdp);
block->gdp = NULL;
diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c
index 5d73e6e49af6..d0ab5019d885 100644
--- a/drivers/s390/block/scm_blk.c
+++ b/drivers/s390/block/scm_blk.c
@@ -118,22 +118,6 @@ static void scm_request_done(struct scm_request *scmrq)
spin_unlock_irqrestore(&list_lock, flags);
}
-static int scm_open(struct block_device *blkdev, fmode_t mode)
-{
- return scm_get_ref();
-}
-
-static void scm_release(struct gendisk *gendisk, fmode_t mode)
-{
- scm_put_ref();
-}
-
-static const struct block_device_operations scm_blk_devops = {
- .owner = THIS_MODULE,
- .open = scm_open,
- .release = scm_release,
-};
-
static bool scm_permit_request(struct scm_blk_dev *bdev, struct request *req)
{
return rq_data_dir(req) != WRITE || bdev->state != SCM_WR_PROHIBIT;
@@ -223,8 +207,12 @@ static void scm_blk_request(struct request_queue *rq)
int ret;
while ((req = blk_peek_request(rq))) {
- if (req->cmd_type != REQ_TYPE_FS)
+ if (req->cmd_type != REQ_TYPE_FS) {
+ blk_start_request(req);
+ blk_dump_rq_flags(req, KMSG_COMPONENT " bad request");
+ blk_end_request_all(req, -EIO);
continue;
+ }
if (!scm_permit_request(bdev, req)) {
scm_ensure_queue_restart(bdev);
@@ -252,7 +240,7 @@ static void scm_blk_request(struct request_queue *rq)
atomic_inc(&bdev->queued_reqs);
blk_start_request(req);
- ret = scm_start_aob(scmrq->aob);
+ ret = eadm_start_aob(scmrq->aob);
if (ret) {
SCM_LOG(5, "no subchannel");
scm_request_requeue(scmrq);
@@ -316,7 +304,7 @@ static void scm_blk_handle_error(struct scm_request *scmrq)
}
restart:
- if (!scm_start_aob(scmrq->aob))
+ if (!eadm_start_aob(scmrq->aob))
return;
requeue:
@@ -359,6 +347,10 @@ static void scm_blk_tasklet(struct scm_blk_dev *bdev)
blk_run_queue(bdev->rq);
}
+static const struct block_device_operations scm_blk_devops = {
+ .owner = THIS_MODULE,
+};
+
int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev)
{
struct request_queue *rq;
diff --git a/drivers/s390/block/scm_blk.h b/drivers/s390/block/scm_blk.h
index 8b387b32fd62..e59331e6c2e5 100644
--- a/drivers/s390/block/scm_blk.h
+++ b/drivers/s390/block/scm_blk.h
@@ -107,7 +107,7 @@ extern debug_info_t *scm_debug;
static inline void SCM_LOG_HEX(int level, void *data, int length)
{
- if (level > scm_debug->level)
+ if (!debug_level_enabled(scm_debug, level))
return;
while (length > 0) {
debug_event(scm_debug, level, data, length);
diff --git a/drivers/s390/block/scm_blk_cluster.c b/drivers/s390/block/scm_blk_cluster.c
index c0d102e3a48b..27f930cd657f 100644
--- a/drivers/s390/block/scm_blk_cluster.c
+++ b/drivers/s390/block/scm_blk_cluster.c
@@ -187,7 +187,7 @@ bool scm_need_cluster_request(struct scm_request *scmrq)
void scm_initiate_cluster_request(struct scm_request *scmrq)
{
scm_prepare_cluster_request(scmrq);
- if (scm_start_aob(scmrq->aob))
+ if (eadm_start_aob(scmrq->aob))
scm_request_requeue(scmrq);
}
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile
index 17821a026c9c..b69ab17f13fa 100644
--- a/drivers/s390/char/Makefile
+++ b/drivers/s390/char/Makefile
@@ -3,7 +3,8 @@
#
obj-y += ctrlchar.o keyboard.o defkeymap.o sclp.o sclp_rw.o sclp_quiesce.o \
- sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o sclp_ctl.o
+ sclp_cmd.o sclp_config.o sclp_cpi_sys.o sclp_ocf.o sclp_ctl.o \
+ sclp_early.o
obj-$(CONFIG_TN3270) += raw3270.o
obj-$(CONFIG_TN3270_CONSOLE) += con3270.o
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index f93cc32eb818..71e974738014 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -564,6 +564,7 @@ static void __exit
fs3270_exit(void)
{
raw3270_unregister_notifier(&fs3270_notifier);
+ device_destroy(class3270, MKDEV(IBM_FS3270_MAJOR, 0));
__unregister_chrdev(IBM_FS3270_MAJOR, 0, 1, "fs3270");
}
diff --git a/drivers/s390/char/monwriter.c b/drivers/s390/char/monwriter.c
index 4600aa10a1c6..668b32b0dc1d 100644
--- a/drivers/s390/char/monwriter.c
+++ b/drivers/s390/char/monwriter.c
@@ -60,7 +60,7 @@ static int monwrite_diag(struct monwrite_hdr *myhdr, char *buffer, int fcn)
struct appldata_product_id id;
int rc;
- strcpy(id.prod_nr, "LNXAPPL");
+ strncpy(id.prod_nr, "LNXAPPL", 7);
id.prod_fn = myhdr->applid;
id.record_nr = myhdr->record_num;
id.version_nr = myhdr->version;
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 24a08e8f19e1..2cdec21e8924 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -615,10 +615,10 @@ raw3270_reset_device_cb(struct raw3270_request *rq, void *data)
if (rp->state != RAW3270_STATE_RESET)
return;
- if (rq && rq->rc) {
+ if (rq->rc) {
/* Reset command failed. */
rp->state = RAW3270_STATE_INIT;
- } else if (0 && MACHINE_IS_VM) {
+ } else if (MACHINE_IS_VM) {
raw3270_size_device_vm(rp);
raw3270_size_device_done(rp);
} else
diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h
index 40d1406289ed..6fbe09686d18 100644
--- a/drivers/s390/char/sclp.h
+++ b/drivers/s390/char/sclp.h
@@ -99,6 +99,7 @@ struct init_sccb {
} __attribute__((packed));
extern u64 sclp_facilities;
+
#define SCLP_HAS_CHP_INFO (sclp_facilities & 0x8000000000000000ULL)
#define SCLP_HAS_CHP_RECONFIG (sclp_facilities & 0x2000000000000000ULL)
#define SCLP_HAS_CPU_INFO (sclp_facilities & 0x0800000000000000ULL)
@@ -179,6 +180,10 @@ void sclp_sdias_exit(void);
extern int sclp_console_pages;
extern int sclp_console_drop;
extern unsigned long sclp_console_full;
+extern u8 sclp_fac84;
+extern unsigned long long sclp_rzm;
+extern unsigned long long sclp_rnmax;
+extern __initdata int sclp_early_read_info_sccb_valid;
/* useful inlines */
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 77df9cb00688..eaa21d542c5c 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -28,168 +28,6 @@
#include "sclp.h"
-#define SCLP_CMDW_READ_SCP_INFO 0x00020001
-#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
-
-struct read_info_sccb {
- struct sccb_header header; /* 0-7 */
- u16 rnmax; /* 8-9 */
- u8 rnsize; /* 10 */
- u8 _reserved0[24 - 11]; /* 11-15 */
- u8 loadparm[8]; /* 24-31 */
- u8 _reserved1[48 - 32]; /* 32-47 */
- u64 facilities; /* 48-55 */
- u8 _reserved2[84 - 56]; /* 56-83 */
- u8 fac84; /* 84 */
- u8 fac85; /* 85 */
- u8 _reserved3[91 - 86]; /* 86-90 */
- u8 flags; /* 91 */
- u8 _reserved4[100 - 92]; /* 92-99 */
- u32 rnsize2; /* 100-103 */
- u64 rnmax2; /* 104-111 */
- u8 _reserved5[4096 - 112]; /* 112-4095 */
-} __attribute__((packed, aligned(PAGE_SIZE)));
-
-static struct init_sccb __initdata early_event_mask_sccb __aligned(PAGE_SIZE);
-static struct read_info_sccb __initdata early_read_info_sccb;
-static int __initdata early_read_info_sccb_valid;
-
-u64 sclp_facilities;
-static u8 sclp_fac84;
-static unsigned long long rzm;
-static unsigned long long rnmax;
-
-static int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb)
-{
- int rc;
-
- __ctl_set_bit(0, 9);
- rc = sclp_service_call(cmd, sccb);
- if (rc)
- goto out;
- __load_psw_mask(PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA |
- PSW_MASK_BA | PSW_MASK_EXT | PSW_MASK_WAIT);
- local_irq_disable();
-out:
- /* Contents of the sccb might have changed. */
- barrier();
- __ctl_clear_bit(0, 9);
- return rc;
-}
-
-static void __init sclp_read_info_early(void)
-{
- int rc;
- int i;
- struct read_info_sccb *sccb;
- sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
- SCLP_CMDW_READ_SCP_INFO};
-
- sccb = &early_read_info_sccb;
- for (i = 0; i < ARRAY_SIZE(commands); i++) {
- do {
- memset(sccb, 0, sizeof(*sccb));
- sccb->header.length = sizeof(*sccb);
- sccb->header.function_code = 0x80;
- sccb->header.control_mask[2] = 0x80;
- rc = sclp_cmd_sync_early(commands[i], sccb);
- } while (rc == -EBUSY);
-
- if (rc)
- break;
- if (sccb->header.response_code == 0x10) {
- early_read_info_sccb_valid = 1;
- break;
- }
- if (sccb->header.response_code != 0x1f0)
- break;
- }
-}
-
-static void __init sclp_event_mask_early(void)
-{
- struct init_sccb *sccb = &early_event_mask_sccb;
- int rc;
-
- do {
- memset(sccb, 0, sizeof(*sccb));
- sccb->header.length = sizeof(*sccb);
- sccb->mask_length = sizeof(sccb_mask_t);
- rc = sclp_cmd_sync_early(SCLP_CMDW_WRITE_EVENT_MASK, sccb);
- } while (rc == -EBUSY);
-}
-
-void __init sclp_facilities_detect(void)
-{
- struct read_info_sccb *sccb;
-
- sclp_read_info_early();
- if (!early_read_info_sccb_valid)
- return;
-
- sccb = &early_read_info_sccb;
- sclp_facilities = sccb->facilities;
- sclp_fac84 = sccb->fac84;
- if (sccb->fac85 & 0x02)
- S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP;
- rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
- rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
- rzm <<= 20;
-
- sclp_event_mask_early();
-}
-
-bool __init sclp_has_linemode(void)
-{
- struct init_sccb *sccb = &early_event_mask_sccb;
-
- if (sccb->header.response_code != 0x20)
- return 0;
- if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK)))
- return 0;
- if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
- return 0;
- return 1;
-}
-
-bool __init sclp_has_vt220(void)
-{
- struct init_sccb *sccb = &early_event_mask_sccb;
-
- if (sccb->header.response_code != 0x20)
- return 0;
- if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK)
- return 1;
- return 0;
-}
-
-unsigned long long sclp_get_rnmax(void)
-{
- return rnmax;
-}
-
-unsigned long long sclp_get_rzm(void)
-{
- return rzm;
-}
-
-/*
- * This function will be called after sclp_facilities_detect(), which gets
- * called from early.c code. Therefore the sccb should have valid contents.
- */
-void __init sclp_get_ipl_info(struct sclp_ipl_info *info)
-{
- struct read_info_sccb *sccb;
-
- if (!early_read_info_sccb_valid)
- return;
- sccb = &early_read_info_sccb;
- info->is_valid = 1;
- if (sccb->flags & 0x2)
- info->has_dump = 1;
- memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN);
-}
-
static void sclp_sync_callback(struct sclp_req *req, void *data)
{
struct completion *completion = data;
@@ -356,14 +194,14 @@ struct assign_storage_sccb {
int arch_get_memory_phys_device(unsigned long start_pfn)
{
- if (!rzm)
+ if (!sclp_rzm)
return 0;
- return PFN_PHYS(start_pfn) >> ilog2(rzm);
+ return PFN_PHYS(start_pfn) >> ilog2(sclp_rzm);
}
static unsigned long long rn2addr(u16 rn)
{
- return (unsigned long long) (rn - 1) * rzm;
+ return (unsigned long long) (rn - 1) * sclp_rzm;
}
static int do_assign_storage(sclp_cmdw_t cmd, u16 rn)
@@ -404,7 +242,7 @@ static int sclp_assign_storage(u16 rn)
if (rc)
return rc;
start = rn2addr(rn);
- storage_key_init_range(start, start + rzm);
+ storage_key_init_range(start, start + sclp_rzm);
return 0;
}
@@ -462,7 +300,7 @@ static int sclp_mem_change_state(unsigned long start, unsigned long size,
istart = rn2addr(incr->rn);
if (start + size - 1 < istart)
break;
- if (start > istart + rzm - 1)
+ if (start > istart + sclp_rzm - 1)
continue;
if (online)
rc |= sclp_assign_storage(incr->rn);
@@ -526,7 +364,7 @@ static void __init add_memory_merged(u16 rn)
if (!first_rn)
goto skip_add;
start = rn2addr(first_rn);
- size = (unsigned long long ) num * rzm;
+ size = (unsigned long long) num * sclp_rzm;
if (start >= VMEM_MAX_PHYS)
goto skip_add;
if (start + size > VMEM_MAX_PHYS)
@@ -574,7 +412,7 @@ static void __init insert_increment(u16 rn, int standby, int assigned)
}
if (!assigned)
new_incr->rn = last_rn + 1;
- if (new_incr->rn > rnmax) {
+ if (new_incr->rn > sclp_rnmax) {
kfree(new_incr);
return;
}
@@ -617,7 +455,7 @@ static int __init sclp_detect_standby_memory(void)
if (OLDMEM_BASE) /* No standby memory in kdump mode */
return 0;
- if (!early_read_info_sccb_valid)
+ if (!sclp_early_read_info_sccb_valid)
return 0;
if ((sclp_facilities & 0xe00000000000ULL) != 0xe00000000000ULL)
return 0;
@@ -661,7 +499,7 @@ static int __init sclp_detect_standby_memory(void)
}
if (rc || list_empty(&sclp_mem_list))
goto out;
- for (i = 1; i <= rnmax - assigned; i++)
+ for (i = 1; i <= sclp_rnmax - assigned; i++)
insert_increment(0, 1, 0);
rc = register_memory_notifier(&sclp_mem_nb);
if (rc)
diff --git a/drivers/s390/char/sclp_early.c b/drivers/s390/char/sclp_early.c
new file mode 100644
index 000000000000..1465e9563101
--- /dev/null
+++ b/drivers/s390/char/sclp_early.c
@@ -0,0 +1,263 @@
+/*
+ * SCLP early driver
+ *
+ * Copyright IBM Corp. 2013
+ */
+
+#define KMSG_COMPONENT "sclp_early"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <asm/ctl_reg.h>
+#include <asm/sclp.h>
+#include <asm/ipl.h>
+#include "sclp_sdias.h"
+#include "sclp.h"
+
+#define SCLP_CMDW_READ_SCP_INFO 0x00020001
+#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
+
+struct read_info_sccb {
+ struct sccb_header header; /* 0-7 */
+ u16 rnmax; /* 8-9 */
+ u8 rnsize; /* 10 */
+ u8 _reserved0[24 - 11]; /* 11-15 */
+ u8 loadparm[8]; /* 24-31 */
+ u8 _reserved1[48 - 32]; /* 32-47 */
+ u64 facilities; /* 48-55 */
+ u8 _reserved2[84 - 56]; /* 56-83 */
+ u8 fac84; /* 84 */
+ u8 fac85; /* 85 */
+ u8 _reserved3[91 - 86]; /* 86-90 */
+ u8 flags; /* 91 */
+ u8 _reserved4[100 - 92]; /* 92-99 */
+ u32 rnsize2; /* 100-103 */
+ u64 rnmax2; /* 104-111 */
+ u8 _reserved5[4096 - 112]; /* 112-4095 */
+} __packed __aligned(PAGE_SIZE);
+
+static __initdata struct read_info_sccb early_read_info_sccb;
+static __initdata char sccb_early[PAGE_SIZE] __aligned(PAGE_SIZE);
+static unsigned long sclp_hsa_size;
+
+__initdata int sclp_early_read_info_sccb_valid;
+u64 sclp_facilities;
+u8 sclp_fac84;
+unsigned long long sclp_rzm;
+unsigned long long sclp_rnmax;
+
+static int __init sclp_cmd_sync_early(sclp_cmdw_t cmd, void *sccb)
+{
+ int rc;
+
+ __ctl_set_bit(0, 9);
+ rc = sclp_service_call(cmd, sccb);
+ if (rc)
+ goto out;
+ __load_psw_mask(PSW_DEFAULT_KEY | PSW_MASK_BASE | PSW_MASK_EA |
+ PSW_MASK_BA | PSW_MASK_EXT | PSW_MASK_WAIT);
+ local_irq_disable();
+out:
+ /* Contents of the sccb might have changed. */
+ barrier();
+ __ctl_clear_bit(0, 9);
+ return rc;
+}
+
+static void __init sclp_read_info_early(void)
+{
+ int rc;
+ int i;
+ struct read_info_sccb *sccb;
+ sclp_cmdw_t commands[] = {SCLP_CMDW_READ_SCP_INFO_FORCED,
+ SCLP_CMDW_READ_SCP_INFO};
+
+ sccb = &early_read_info_sccb;
+ for (i = 0; i < ARRAY_SIZE(commands); i++) {
+ do {
+ memset(sccb, 0, sizeof(*sccb));
+ sccb->header.length = sizeof(*sccb);
+ sccb->header.function_code = 0x80;
+ sccb->header.control_mask[2] = 0x80;
+ rc = sclp_cmd_sync_early(commands[i], sccb);
+ } while (rc == -EBUSY);
+
+ if (rc)
+ break;
+ if (sccb->header.response_code == 0x10) {
+ sclp_early_read_info_sccb_valid = 1;
+ break;
+ }
+ if (sccb->header.response_code != 0x1f0)
+ break;
+ }
+}
+
+static void __init sclp_facilities_detect(void)
+{
+ struct read_info_sccb *sccb;
+
+ sclp_read_info_early();
+ if (!sclp_early_read_info_sccb_valid)
+ return;
+
+ sccb = &early_read_info_sccb;
+ sclp_facilities = sccb->facilities;
+ sclp_fac84 = sccb->fac84;
+ if (sccb->fac85 & 0x02)
+ S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP;
+ sclp_rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
+ sclp_rzm = sccb->rnsize ? sccb->rnsize : sccb->rnsize2;
+ sclp_rzm <<= 20;
+}
+
+bool __init sclp_has_linemode(void)
+{
+ struct init_sccb *sccb = (void *) &sccb_early;
+
+ if (sccb->header.response_code != 0x20)
+ return 0;
+ if (!(sccb->sclp_send_mask & (EVTYP_OPCMD_MASK | EVTYP_PMSGCMD_MASK)))
+ return 0;
+ if (!(sccb->sclp_receive_mask & (EVTYP_MSG_MASK | EVTYP_PMSGCMD_MASK)))
+ return 0;
+ return 1;
+}
+
+bool __init sclp_has_vt220(void)
+{
+ struct init_sccb *sccb = (void *) &sccb_early;
+
+ if (sccb->header.response_code != 0x20)
+ return 0;
+ if (sccb->sclp_send_mask & EVTYP_VT220MSG_MASK)
+ return 1;
+ return 0;
+}
+
+unsigned long long sclp_get_rnmax(void)
+{
+ return sclp_rnmax;
+}
+
+unsigned long long sclp_get_rzm(void)
+{
+ return sclp_rzm;
+}
+
+/*
+ * This function will be called after sclp_facilities_detect(), which gets
+ * called from early.c code. Therefore the sccb should have valid contents.
+ */
+void __init sclp_get_ipl_info(struct sclp_ipl_info *info)
+{
+ struct read_info_sccb *sccb;
+
+ if (!sclp_early_read_info_sccb_valid)
+ return;
+ sccb = &early_read_info_sccb;
+ info->is_valid = 1;
+ if (sccb->flags & 0x2)
+ info->has_dump = 1;
+ memcpy(&info->loadparm, &sccb->loadparm, LOADPARM_LEN);
+}
+
+static int __init sclp_cmd_early(sclp_cmdw_t cmd, void *sccb)
+{
+ int rc;
+
+ do {
+ rc = sclp_cmd_sync_early(cmd, sccb);
+ } while (rc == -EBUSY);
+
+ if (rc)
+ return -EIO;
+ if (((struct sccb_header *) sccb)->response_code != 0x0020)
+ return -EIO;
+ return 0;
+}
+
+static void __init sccb_init_eq_size(struct sdias_sccb *sccb)
+{
+ memset(sccb, 0, sizeof(*sccb));
+
+ sccb->hdr.length = sizeof(*sccb);
+ sccb->evbuf.hdr.length = sizeof(struct sdias_evbuf);
+ sccb->evbuf.hdr.type = EVTYP_SDIAS;
+ sccb->evbuf.event_qual = SDIAS_EQ_SIZE;
+ sccb->evbuf.data_id = SDIAS_DI_FCP_DUMP;
+ sccb->evbuf.event_id = 4712;
+ sccb->evbuf.dbs = 1;
+}
+
+static int __init sclp_set_event_mask(unsigned long receive_mask,
+ unsigned long send_mask)
+{
+ struct init_sccb *sccb = (void *) &sccb_early;
+
+ memset(sccb, 0, sizeof(*sccb));
+ sccb->header.length = sizeof(*sccb);
+ sccb->mask_length = sizeof(sccb_mask_t);
+ sccb->receive_mask = receive_mask;
+ sccb->send_mask = send_mask;
+ return sclp_cmd_early(SCLP_CMDW_WRITE_EVENT_MASK, sccb);
+}
+
+static long __init sclp_hsa_size_init(void)
+{
+ struct sdias_sccb *sccb = (void *) &sccb_early;
+
+ sccb_init_eq_size(sccb);
+ if (sclp_cmd_early(SCLP_CMDW_WRITE_EVENT_DATA, sccb))
+ return -EIO;
+ if (sccb->evbuf.blk_cnt != 0)
+ return (sccb->evbuf.blk_cnt - 1) * PAGE_SIZE;
+ return 0;
+}
+
+static long __init sclp_hsa_copy_wait(void)
+{
+ struct sccb_header *sccb = (void *) &sccb_early;
+
+ memset(sccb, 0, PAGE_SIZE);
+ sccb->length = PAGE_SIZE;
+ if (sclp_cmd_early(SCLP_CMDW_READ_EVENT_DATA, sccb))
+ return -EIO;
+ return (((struct sdias_sccb *) sccb)->evbuf.blk_cnt - 1) * PAGE_SIZE;
+}
+
+unsigned long sclp_get_hsa_size(void)
+{
+ return sclp_hsa_size;
+}
+
+static void __init sclp_hsa_size_detect(void)
+{
+ long size;
+
+ /* First try synchronous interface (LPAR) */
+ if (sclp_set_event_mask(0, 0x40000010))
+ return;
+ size = sclp_hsa_size_init();
+ if (size < 0)
+ return;
+ if (size != 0)
+ goto out;
+ /* Then try asynchronous interface (z/VM) */
+ if (sclp_set_event_mask(0x00000010, 0x40000010))
+ return;
+ size = sclp_hsa_size_init();
+ if (size < 0)
+ return;
+ size = sclp_hsa_copy_wait();
+ if (size < 0)
+ return;
+out:
+ sclp_hsa_size = size;
+}
+
+void __init sclp_early_detect(void)
+{
+ sclp_facilities_detect();
+ sclp_hsa_size_detect();
+ sclp_set_event_mask(0, 0);
+}
diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c
index b1032931a1c4..561a0414b352 100644
--- a/drivers/s390/char/sclp_sdias.c
+++ b/drivers/s390/char/sclp_sdias.c
@@ -1,7 +1,7 @@
/*
- * Sclp "store data in absolut storage"
+ * SCLP "store data in absolute storage"
*
- * Copyright IBM Corp. 2003, 2007
+ * Copyright IBM Corp. 2003, 2013
* Author(s): Michael Holzheu
*/
@@ -14,6 +14,7 @@
#include <asm/debug.h>
#include <asm/ipl.h>
+#include "sclp_sdias.h"
#include "sclp.h"
#include "sclp_rw.h"
@@ -22,46 +23,12 @@
#define SDIAS_RETRIES 300
#define SDIAS_SLEEP_TICKS 50
-#define EQ_STORE_DATA 0x0
-#define EQ_SIZE 0x1
-#define DI_FCP_DUMP 0x0
-#define ASA_SIZE_32 0x0
-#define ASA_SIZE_64 0x1
-#define EVSTATE_ALL_STORED 0x0
-#define EVSTATE_NO_DATA 0x3
-#define EVSTATE_PART_STORED 0x10
-
static struct debug_info *sdias_dbf;
static struct sclp_register sclp_sdias_register = {
.send_mask = EVTYP_SDIAS_MASK,
};
-struct sdias_evbuf {
- struct evbuf_header hdr;
- u8 event_qual;
- u8 data_id;
- u64 reserved2;
- u32 event_id;
- u16 reserved3;
- u8 asa_size;
- u8 event_status;
- u32 reserved4;
- u32 blk_cnt;
- u64 asa;
- u32 reserved5;
- u32 fbn;
- u32 reserved6;
- u32 lbn;
- u16 reserved7;
- u16 dbs;
-} __attribute__((packed));
-
-struct sdias_sccb {
- struct sccb_header hdr;
- struct sdias_evbuf evbuf;
-} __attribute__((packed));
-
static struct sdias_sccb sccb __attribute__((aligned(4096)));
static struct sdias_evbuf sdias_evbuf;
@@ -148,8 +115,8 @@ int sclp_sdias_blk_count(void)
sccb.hdr.length = sizeof(sccb);
sccb.evbuf.hdr.length = sizeof(struct sdias_evbuf);
sccb.evbuf.hdr.type = EVTYP_SDIAS;
- sccb.evbuf.event_qual = EQ_SIZE;
- sccb.evbuf.data_id = DI_FCP_DUMP;
+ sccb.evbuf.event_qual = SDIAS_EQ_SIZE;
+ sccb.evbuf.data_id = SDIAS_DI_FCP_DUMP;
sccb.evbuf.event_id = 4712;
sccb.evbuf.dbs = 1;
@@ -208,13 +175,13 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks)
sccb.evbuf.hdr.length = sizeof(struct sdias_evbuf);
sccb.evbuf.hdr.type = EVTYP_SDIAS;
sccb.evbuf.hdr.flags = 0;
- sccb.evbuf.event_qual = EQ_STORE_DATA;
- sccb.evbuf.data_id = DI_FCP_DUMP;
+ sccb.evbuf.event_qual = SDIAS_EQ_STORE_DATA;
+ sccb.evbuf.data_id = SDIAS_DI_FCP_DUMP;
sccb.evbuf.event_id = 4712;
#ifdef CONFIG_64BIT
- sccb.evbuf.asa_size = ASA_SIZE_64;
+ sccb.evbuf.asa_size = SDIAS_ASA_SIZE_64;
#else
- sccb.evbuf.asa_size = ASA_SIZE_32;
+ sccb.evbuf.asa_size = SDIAS_ASA_SIZE_32;
#endif
sccb.evbuf.event_status = 0;
sccb.evbuf.blk_cnt = nr_blks;
@@ -240,20 +207,19 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks)
}
switch (sdias_evbuf.event_status) {
- case EVSTATE_ALL_STORED:
- TRACE("all stored\n");
- break;
- case EVSTATE_PART_STORED:
- TRACE("part stored: %i\n", sdias_evbuf.blk_cnt);
- break;
- case EVSTATE_NO_DATA:
- TRACE("no data\n");
- /* fall through */
- default:
- pr_err("Error from SCLP while copying hsa. "
- "Event status = %x\n",
- sdias_evbuf.event_status);
- rc = -EIO;
+ case SDIAS_EVSTATE_ALL_STORED:
+ TRACE("all stored\n");
+ break;
+ case SDIAS_EVSTATE_PART_STORED:
+ TRACE("part stored: %i\n", sdias_evbuf.blk_cnt);
+ break;
+ case SDIAS_EVSTATE_NO_DATA:
+ TRACE("no data\n");
+ /* fall through */
+ default:
+ pr_err("Error from SCLP while copying hsa. Event status = %x\n",
+ sdias_evbuf.event_status);
+ rc = -EIO;
}
out:
mutex_unlock(&sdias_mutex);
diff --git a/drivers/s390/char/sclp_sdias.h b/drivers/s390/char/sclp_sdias.h
new file mode 100644
index 000000000000..f2431c414150
--- /dev/null
+++ b/drivers/s390/char/sclp_sdias.h
@@ -0,0 +1,46 @@
+/*
+ * SCLP "store data in absolute storage"
+ *
+ * Copyright IBM Corp. 2003, 2013
+ */
+
+#ifndef SCLP_SDIAS_H
+#define SCLP_SDIAS_H
+
+#include "sclp.h"
+
+#define SDIAS_EQ_STORE_DATA 0x0
+#define SDIAS_EQ_SIZE 0x1
+#define SDIAS_DI_FCP_DUMP 0x0
+#define SDIAS_ASA_SIZE_32 0x0
+#define SDIAS_ASA_SIZE_64 0x1
+#define SDIAS_EVSTATE_ALL_STORED 0x0
+#define SDIAS_EVSTATE_NO_DATA 0x3
+#define SDIAS_EVSTATE_PART_STORED 0x10
+
+struct sdias_evbuf {
+ struct evbuf_header hdr;
+ u8 event_qual;
+ u8 data_id;
+ u64 reserved2;
+ u32 event_id;
+ u16 reserved3;
+ u8 asa_size;
+ u8 event_status;
+ u32 reserved4;
+ u32 blk_cnt;
+ u64 asa;
+ u32 reserved5;
+ u32 fbn;
+ u32 reserved6;
+ u32 lbn;
+ u16 reserved7;
+ u16 dbs;
+} __packed;
+
+struct sdias_sccb {
+ struct sccb_header hdr;
+ struct sdias_evbuf evbuf;
+} __packed;
+
+#endif /* SCLP_SDIAS_H */
diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c
index 3f4ca4e09a4c..34629ea913d4 100644
--- a/drivers/s390/char/tty3270.c
+++ b/drivers/s390/char/tty3270.c
@@ -942,7 +942,7 @@ static int tty3270_install(struct tty_driver *driver, struct tty_struct *tty)
return rc;
}
- tp->screen = tty3270_alloc_screen(tp->view.cols, tp->view.rows);
+ tp->screen = tty3270_alloc_screen(tp->view.rows, tp->view.cols);
if (IS_ERR(tp->screen)) {
rc = PTR_ERR(tp->screen);
raw3270_put_view(&tp->view);
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index 794820a123d0..3d8e4d63f514 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -151,7 +151,7 @@ static int __init init_cpu_info(enum arch_id arch)
/* get info for boot cpu from lowcore, stored in the HSA */
- sa = kmalloc(sizeof(*sa), GFP_KERNEL);
+ sa = dump_save_area_create(0);
if (!sa)
return -ENOMEM;
if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) {
@@ -159,7 +159,6 @@ static int __init init_cpu_info(enum arch_id arch)
kfree(sa);
return -EIO;
}
- zfcpdump_save_areas[0] = sa;
return 0;
}
@@ -246,24 +245,25 @@ static int copy_lc(void __user *buf, void *sa, int sa_off, int len)
static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
{
unsigned long end;
- int i = 0;
+ int i;
if (count == 0)
return 0;
end = start + count;
- while (zfcpdump_save_areas[i]) {
+ for (i = 0; i < dump_save_areas.count; i++) {
unsigned long cp_start, cp_end; /* copy range */
unsigned long sa_start, sa_end; /* save area range */
unsigned long prefix;
unsigned long sa_off, len, buf_off;
+ struct save_area *save_area = dump_save_areas.areas[i];
- prefix = zfcpdump_save_areas[i]->pref_reg;
+ prefix = save_area->pref_reg;
sa_start = prefix + sys_info.sa_base;
sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
if ((end < sa_start) || (start > sa_end))
- goto next;
+ continue;
cp_start = max(start, sa_start);
cp_end = min(end, sa_end);
@@ -272,10 +272,8 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
len = cp_end - cp_start;
TRACE("copy_lc for: %lx\n", start);
- if (copy_lc(buf + buf_off, zfcpdump_save_areas[i], sa_off, len))
+ if (copy_lc(buf + buf_off, save_area, sa_off, len))
return -EFAULT;
-next:
- i++;
}
return 0;
}
@@ -330,9 +328,9 @@ static ssize_t zcore_read(struct file *file, char __user *buf, size_t count,
mem_offs = 0;
/* Copy from HSA data */
- if (*ppos < (ZFCPDUMP_HSA_SIZE + HEADER_SIZE)) {
- size = min((count - hdr_count), (size_t) (ZFCPDUMP_HSA_SIZE
- - mem_start));
+ if (*ppos < sclp_get_hsa_size() + HEADER_SIZE) {
+ size = min((count - hdr_count),
+ (size_t) (sclp_get_hsa_size() - mem_start));
rc = memcpy_hsa_user(buf + hdr_count, mem_start, size);
if (rc)
goto fail;
@@ -492,7 +490,7 @@ static ssize_t zcore_hsa_read(struct file *filp, char __user *buf,
static char str[18];
if (hsa_available)
- snprintf(str, sizeof(str), "%lx\n", ZFCPDUMP_HSA_SIZE);
+ snprintf(str, sizeof(str), "%lx\n", sclp_get_hsa_size());
else
snprintf(str, sizeof(str), "0\n");
return simple_read_from_buffer(buf, count, ppos, str, strlen(str));
@@ -586,17 +584,9 @@ static int __init sys_info_init(enum arch_id arch, unsigned long mem_end)
static int __init check_sdias(void)
{
- int rc, act_hsa_size;
-
- rc = sclp_sdias_blk_count();
- if (rc < 0) {
+ if (!sclp_get_hsa_size()) {
TRACE("Could not determine HSA size\n");
- return rc;
- }
- act_hsa_size = (rc - 1) * PAGE_SIZE;
- if (act_hsa_size < ZFCPDUMP_HSA_SIZE) {
- TRACE("HSA size too small: %i\n", act_hsa_size);
- return -EINVAL;
+ return -ENODEV;
}
return 0;
}
@@ -637,8 +627,8 @@ static void __init zcore_header_init(int arch, struct zcore_header *hdr,
hdr->num_pages = mem_size / PAGE_SIZE;
hdr->tod = get_tod_clock();
get_cpu_id(&hdr->cpu_id);
- for (i = 0; zfcpdump_save_areas[i]; i++) {
- prefix = zfcpdump_save_areas[i]->pref_reg;
+ for (i = 0; i < dump_save_areas.count; i++) {
+ prefix = dump_save_areas.areas[i]->pref_reg;
hdr->real_cpu_cnt++;
if (!prefix)
continue;
@@ -664,7 +654,7 @@ static int __init zcore_reipl_init(void)
ipl_block = (void *) __get_free_page(GFP_KERNEL);
if (!ipl_block)
return -ENOMEM;
- if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
+ if (ipib_info.ipib < sclp_get_hsa_size())
rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
else
rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c
index d028fd800c9c..f055df0b167f 100644
--- a/drivers/s390/cio/airq.c
+++ b/drivers/s390/cio/airq.c
@@ -194,15 +194,14 @@ EXPORT_SYMBOL(airq_iv_release);
*/
unsigned long airq_iv_alloc_bit(struct airq_iv *iv)
{
- const unsigned long be_to_le = BITS_PER_LONG - 1;
unsigned long bit;
if (!iv->avail)
return -1UL;
spin_lock(&iv->lock);
- bit = find_first_bit_left(iv->avail, iv->bits);
+ bit = find_first_bit_inv(iv->avail, iv->bits);
if (bit < iv->bits) {
- clear_bit(bit ^ be_to_le, iv->avail);
+ clear_bit_inv(bit, iv->avail);
if (bit >= iv->end)
iv->end = bit + 1;
} else
@@ -220,19 +219,17 @@ EXPORT_SYMBOL(airq_iv_alloc_bit);
*/
void airq_iv_free_bit(struct airq_iv *iv, unsigned long bit)
{
- const unsigned long be_to_le = BITS_PER_LONG - 1;
-
if (!iv->avail)
return;
spin_lock(&iv->lock);
/* Clear (possibly left over) interrupt bit */
- clear_bit(bit ^ be_to_le, iv->vector);
+ clear_bit_inv(bit, iv->vector);
/* Make the bit position available again */
- set_bit(bit ^ be_to_le, iv->avail);
+ set_bit_inv(bit, iv->avail);
if (bit == iv->end - 1) {
/* Find new end of bit-field */
while (--iv->end > 0)
- if (!test_bit((iv->end - 1) ^ be_to_le, iv->avail))
+ if (!test_bit_inv(iv->end - 1, iv->avail))
break;
}
spin_unlock(&iv->lock);
@@ -251,15 +248,13 @@ EXPORT_SYMBOL(airq_iv_free_bit);
unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start,
unsigned long end)
{
- const unsigned long be_to_le = BITS_PER_LONG - 1;
unsigned long bit;
/* Find non-zero bit starting from 'ivs->next'. */
- bit = find_next_bit_left(iv->vector, end, start);
+ bit = find_next_bit_inv(iv->vector, end, start);
if (bit >= end)
return -1UL;
- /* Clear interrupt bit (find left uses big-endian bit numbers) */
- clear_bit(bit ^ be_to_le, iv->vector);
+ clear_bit_inv(bit, iv->vector);
return bit;
}
EXPORT_SYMBOL(airq_iv_scan);
diff --git a/drivers/s390/cio/eadm_sch.c b/drivers/s390/cio/eadm_sch.c
index d9eddcba7e88..3a2ee4a740b4 100644
--- a/drivers/s390/cio/eadm_sch.c
+++ b/drivers/s390/cio/eadm_sch.c
@@ -6,6 +6,7 @@
*/
#include <linux/kernel_stat.h>
+#include <linux/completion.h>
#include <linux/workqueue.h>
#include <linux/spinlock.h>
#include <linux/device.h>
@@ -42,7 +43,7 @@ static debug_info_t *eadm_debug;
static void EADM_LOG_HEX(int level, void *data, int length)
{
- if (level > eadm_debug->level)
+ if (!debug_level_enabled(eadm_debug, level))
return;
while (length > 0) {
debug_event(eadm_debug, level, data, length);
@@ -159,6 +160,9 @@ static void eadm_subchannel_irq(struct subchannel *sch)
}
scm_irq_handler((struct aob *)(unsigned long)scsw->aob, error);
private->state = EADM_IDLE;
+
+ if (private->completion)
+ complete(private->completion);
}
static struct subchannel *eadm_get_idle_sch(void)
@@ -186,7 +190,7 @@ static struct subchannel *eadm_get_idle_sch(void)
return NULL;
}
-static int eadm_start_aob(struct aob *aob)
+int eadm_start_aob(struct aob *aob)
{
struct eadm_private *private;
struct subchannel *sch;
@@ -214,6 +218,7 @@ out_unlock:
return ret;
}
+EXPORT_SYMBOL_GPL(eadm_start_aob);
static int eadm_subchannel_probe(struct subchannel *sch)
{
@@ -255,13 +260,32 @@ out:
static void eadm_quiesce(struct subchannel *sch)
{
+ struct eadm_private *private = get_eadm_private(sch);
+ DECLARE_COMPLETION_ONSTACK(completion);
int ret;
+ spin_lock_irq(sch->lock);
+ if (private->state != EADM_BUSY)
+ goto disable;
+
+ if (eadm_subchannel_clear(sch))
+ goto disable;
+
+ private->completion = &completion;
+ spin_unlock_irq(sch->lock);
+
+ wait_for_completion_io(&completion);
+
+ spin_lock_irq(sch->lock);
+ private->completion = NULL;
+
+disable:
+ eadm_subchannel_set_timeout(sch, 0);
do {
- spin_lock_irq(sch->lock);
ret = cio_disable_subchannel(sch);
- spin_unlock_irq(sch->lock);
} while (ret == -EBUSY);
+
+ spin_unlock_irq(sch->lock);
}
static int eadm_subchannel_remove(struct subchannel *sch)
@@ -357,11 +381,6 @@ static struct css_driver eadm_subchannel_driver = {
.restore = eadm_subchannel_restore,
};
-static struct eadm_ops eadm_ops = {
- .eadm_start = eadm_start_aob,
- .owner = THIS_MODULE,
-};
-
static int __init eadm_sch_init(void)
{
int ret;
@@ -381,7 +400,6 @@ static int __init eadm_sch_init(void)
if (ret)
goto cleanup;
- register_eadm_ops(&eadm_ops);
return ret;
cleanup:
@@ -392,7 +410,6 @@ cleanup:
static void __exit eadm_sch_exit(void)
{
- unregister_eadm_ops(&eadm_ops);
css_driver_unregister(&eadm_subchannel_driver);
isc_unregister(EADM_SCH_ISC);
debug_unregister(eadm_debug);
diff --git a/drivers/s390/cio/eadm_sch.h b/drivers/s390/cio/eadm_sch.h
index 2779be093982..9664e4653f98 100644
--- a/drivers/s390/cio/eadm_sch.h
+++ b/drivers/s390/cio/eadm_sch.h
@@ -1,6 +1,7 @@
#ifndef EADM_SCH_H
#define EADM_SCH_H
+#include <linux/completion.h>
#include <linux/device.h>
#include <linux/timer.h>
#include <linux/list.h>
@@ -9,9 +10,10 @@
struct eadm_private {
union orb orb;
enum {EADM_IDLE, EADM_BUSY, EADM_NOT_OPER} state;
+ struct completion *completion;
+ struct subchannel *sch;
struct timer_list timer;
struct list_head head;
- struct subchannel *sch;
} __aligned(8);
#define get_eadm_private(n) ((struct eadm_private *)dev_get_drvdata(&n->dev))
diff --git a/drivers/s390/cio/qdio_debug.h b/drivers/s390/cio/qdio_debug.h
index 647b422bb22a..dfac9bfefea3 100644
--- a/drivers/s390/cio/qdio_debug.h
+++ b/drivers/s390/cio/qdio_debug.h
@@ -16,12 +16,6 @@
extern debug_info_t *qdio_dbf_setup;
extern debug_info_t *qdio_dbf_error;
-/* sort out low debug levels early to avoid wasted sprints */
-static inline int qdio_dbf_passes(debug_info_t *dbf_grp, int level)
-{
- return (level <= dbf_grp->level);
-}
-
#define DBF_ERR 3 /* error conditions */
#define DBF_WARN 4 /* warning conditions */
#define DBF_INFO 6 /* informational */
@@ -65,7 +59,7 @@ static inline void DBF_ERROR_HEX(void *addr, int len)
#define DBF_DEV_EVENT(level, device, text...) \
do { \
char debug_buffer[QDIO_DBF_LEN]; \
- if (qdio_dbf_passes(device->debug_area, level)) { \
+ if (debug_level_enabled(device->debug_area, level)) { \
snprintf(debug_buffer, QDIO_DBF_LEN, text); \
debug_text_event(device->debug_area, level, debug_buffer); \
} \
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index bbd3e511c771..3e602e8affa7 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -528,7 +528,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
case SLSB_P_INPUT_PRIMED:
inbound_primed(q, count);
q->first_to_check = add_buf(q->first_to_check, count);
- if (atomic_sub(count, &q->nr_buf_used) == 0)
+ if (atomic_sub_return(count, &q->nr_buf_used) == 0)
qperf_inc(q, inbound_queue_full);
if (q->irq_ptr->perf_stat_enabled)
account_sbals(q, count);
diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c
index 46ec25632e8b..15268edc54ae 100644
--- a/drivers/s390/cio/scm.c
+++ b/drivers/s390/cio/scm.c
@@ -15,8 +15,6 @@
#include "chsc.h"
static struct device *scm_root;
-static struct eadm_ops *eadm_ops;
-static DEFINE_MUTEX(eadm_ops_mutex);
#define to_scm_dev(n) container_of(n, struct scm_device, dev)
#define to_scm_drv(d) container_of(d, struct scm_driver, drv)
@@ -73,49 +71,6 @@ void scm_driver_unregister(struct scm_driver *scmdrv)
}
EXPORT_SYMBOL_GPL(scm_driver_unregister);
-int scm_get_ref(void)
-{
- int ret = 0;
-
- mutex_lock(&eadm_ops_mutex);
- if (!eadm_ops || !try_module_get(eadm_ops->owner))
- ret = -ENOENT;
- mutex_unlock(&eadm_ops_mutex);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(scm_get_ref);
-
-void scm_put_ref(void)
-{
- mutex_lock(&eadm_ops_mutex);
- module_put(eadm_ops->owner);
- mutex_unlock(&eadm_ops_mutex);
-}
-EXPORT_SYMBOL_GPL(scm_put_ref);
-
-void register_eadm_ops(struct eadm_ops *ops)
-{
- mutex_lock(&eadm_ops_mutex);
- eadm_ops = ops;
- mutex_unlock(&eadm_ops_mutex);
-}
-EXPORT_SYMBOL_GPL(register_eadm_ops);
-
-void unregister_eadm_ops(struct eadm_ops *ops)
-{
- mutex_lock(&eadm_ops_mutex);
- eadm_ops = NULL;
- mutex_unlock(&eadm_ops_mutex);
-}
-EXPORT_SYMBOL_GPL(unregister_eadm_ops);
-
-int scm_start_aob(struct aob *aob)
-{
- return eadm_ops->eadm_start(aob);
-}
-EXPORT_SYMBOL_GPL(scm_start_aob);
-
void scm_irq_handler(struct aob *aob, int error)
{
struct aob_rq_header *aobrq = (void *) aob->request.data;
diff --git a/drivers/s390/crypto/zcrypt_debug.h b/drivers/s390/crypto/zcrypt_debug.h
index 841ea72e4a4e..28d9349de1ad 100644
--- a/drivers/s390/crypto/zcrypt_debug.h
+++ b/drivers/s390/crypto/zcrypt_debug.h
@@ -11,12 +11,6 @@
/* that gives us 15 characters in the text event views */
#define ZCRYPT_DBF_LEN 16
-/* sort out low debug levels early to avoid wasted sprints */
-static inline int zcrypt_dbf_passes(debug_info_t *dbf_grp, int level)
-{
- return (level <= dbf_grp->level);
-}
-
#define DBF_ERR 3 /* error conditions */
#define DBF_WARN 4 /* warning conditions */
#define DBF_INFO 6 /* informational */
@@ -25,7 +19,7 @@ static inline int zcrypt_dbf_passes(debug_info_t *dbf_grp, int level)
#define ZCRYPT_DBF_COMMON(level, text...) \
do { \
- if (zcrypt_dbf_passes(zcrypt_dbf_common, level)) { \
+ if (debug_level_enabled(zcrypt_dbf_common, level)) { \
char debug_buffer[ZCRYPT_DBF_LEN]; \
snprintf(debug_buffer, ZCRYPT_DBF_LEN, text); \
debug_text_event(zcrypt_dbf_common, level, \
@@ -35,7 +29,7 @@ static inline int zcrypt_dbf_passes(debug_info_t *dbf_grp, int level)
#define ZCRYPT_DBF_DEVICES(level, text...) \
do { \
- if (zcrypt_dbf_passes(zcrypt_dbf_devices, level)) { \
+ if (debug_level_enabled(zcrypt_dbf_devices, level)) { \
char debug_buffer[ZCRYPT_DBF_LEN]; \
snprintf(debug_buffer, ZCRYPT_DBF_LEN, text); \
debug_text_event(zcrypt_dbf_devices, level, \
@@ -45,7 +39,7 @@ static inline int zcrypt_dbf_passes(debug_info_t *dbf_grp, int level)
#define ZCRYPT_DBF_DEV(level, device, text...) \
do { \
- if (zcrypt_dbf_passes(device->dbf_area, level)) { \
+ if (debug_level_enabled(device->dbf_area, level)) { \
char debug_buffer[ZCRYPT_DBF_LEN]; \
snprintf(debug_buffer, ZCRYPT_DBF_LEN, text); \
debug_text_event(device->dbf_area, level, \
diff --git a/drivers/s390/kvm/kvm_virtio.c b/drivers/s390/kvm/kvm_virtio.c
index af2166fa5159..1abd0db29915 100644
--- a/drivers/s390/kvm/kvm_virtio.c
+++ b/drivers/s390/kvm/kvm_virtio.c
@@ -166,11 +166,15 @@ static void kvm_reset(struct virtio_device *vdev)
* make a hypercall. We hand the address of the virtqueue so the Host
* knows which virtqueue we're talking about.
*/
-static void kvm_notify(struct virtqueue *vq)
+static bool kvm_notify(struct virtqueue *vq)
{
+ long rc;
struct kvm_vqconfig *config = vq->priv;
- kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, config->address);
+ rc = kvm_hypercall1(KVM_S390_VIRTIO_NOTIFY, config->address);
+ if (rc < 0)
+ return false;
+ return true;
}
/*
diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c
index 779dc5136291..d6297176ab85 100644
--- a/drivers/s390/kvm/virtio_ccw.c
+++ b/drivers/s390/kvm/virtio_ccw.c
@@ -162,7 +162,7 @@ static inline long do_kvm_notify(struct subchannel_id schid,
return __rc;
}
-static void virtio_ccw_kvm_notify(struct virtqueue *vq)
+static bool virtio_ccw_kvm_notify(struct virtqueue *vq)
{
struct virtio_ccw_vq_info *info = vq->priv;
struct virtio_ccw_device *vcdev;
@@ -171,6 +171,9 @@ static void virtio_ccw_kvm_notify(struct virtqueue *vq)
vcdev = to_vc_device(info->vq->vdev);
ccw_device_get_schid(vcdev->cdev, &schid);
info->cookie = do_kvm_notify(schid, vq->index, info->cookie);
+ if (info->cookie < 0)
+ return false;
+ return true;
}
static int virtio_ccw_read_vq_conf(struct virtio_ccw_device *vcdev,
diff --git a/drivers/s390/net/claw.h b/drivers/s390/net/claw.h
index 1bc5904df19f..3339b9b607b3 100644
--- a/drivers/s390/net/claw.h
+++ b/drivers/s390/net/claw.h
@@ -114,15 +114,9 @@ do { \
debug_event(claw_dbf_##name,level,(void*)(addr),len); \
} while (0)
-/* Allow to sort out low debug levels early to avoid wasted sprints */
-static inline int claw_dbf_passes(debug_info_t *dbf_grp, int level)
-{
- return (level <= dbf_grp->level);
-}
-
#define CLAW_DBF_TEXT_(level,name,text...) \
do { \
- if (claw_dbf_passes(claw_dbf_##name, level)) { \
+ if (debug_level_enabled(claw_dbf_##name, level)) { \
sprintf(debug_buffer, text); \
debug_text_event(claw_dbf_##name, level, \
debug_buffer); \
diff --git a/drivers/s390/net/ctcm_dbug.c b/drivers/s390/net/ctcm_dbug.c
index 6514e1cb3f1c..8363f1c966ef 100644
--- a/drivers/s390/net/ctcm_dbug.c
+++ b/drivers/s390/net/ctcm_dbug.c
@@ -66,7 +66,7 @@ void ctcm_dbf_longtext(enum ctcm_dbf_names dbf_nix, int level, char *fmt, ...)
char dbf_txt_buf[64];
va_list args;
- if (level > (ctcm_dbf[dbf_nix].id)->level)
+ if (!debug_level_enabled(ctcm_dbf[dbf_nix].id, level))
return;
va_start(args, fmt);
vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args);
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index 8c03392ac833..150fcb4cebc3 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -16,15 +16,9 @@ do { \
debug_event(lcs_dbf_##name,level,(void*)(addr),len); \
} while (0)
-/* Allow to sort out low debug levels early to avoid wasted sprints */
-static inline int lcs_dbf_passes(debug_info_t *dbf_grp, int level)
-{
- return (level <= dbf_grp->level);
-}
-
#define LCS_DBF_TEXT_(level,name,text...) \
do { \
- if (lcs_dbf_passes(lcs_dbf_##name, level)) { \
+ if (debug_level_enabled(lcs_dbf_##name, level)) { \
sprintf(debug_buffer, text); \
debug_text_event(lcs_dbf_##name, level, debug_buffer); \
} \
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index 279ad504ec3c..9b333fcf1a4c 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -105,15 +105,9 @@ MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf);
-/* Allow to sort out low debug levels early to avoid wasted sprints */
-static inline int iucv_dbf_passes(debug_info_t *dbf_grp, int level)
-{
- return (level <= dbf_grp->level);
-}
-
#define IUCV_DBF_TEXT_(name, level, text...) \
do { \
- if (iucv_dbf_passes(iucv_dbf_##name, level)) { \
+ if (debug_level_enabled(iucv_dbf_##name, level)) { \
char* __buf = get_cpu_var(iucv_dbf_txt_buf); \
sprintf(__buf, text); \
debug_text_event(iucv_dbf_##name, level, __buf); \
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 0a328d0d11be..eb4e1f809feb 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -4451,7 +4451,7 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata)
struct qeth_cmd_buffer *iob;
struct qeth_ipa_cmd *cmd;
struct qeth_snmp_ureq *ureq;
- int req_len;
+ unsigned int req_len;
struct qeth_arp_query_info qinfo = {0, };
int rc = 0;
@@ -4467,6 +4467,10 @@ int qeth_snmp_command(struct qeth_card *card, char __user *udata)
/* skip 4 bytes (data_len struct member) to get req_len */
if (copy_from_user(&req_len, udata + sizeof(int), sizeof(int)))
return -EFAULT;
+ if (req_len > (QETH_BUFSIZE - IPA_PDU_HEADER_SIZE -
+ sizeof(struct qeth_ipacmd_hdr) -
+ sizeof(struct qeth_ipacmd_setadpparms_hdr)))
+ return -EINVAL;
ureq = memdup_user(udata, req_len + sizeof(struct qeth_snmp_ureq_hdr));
if (IS_ERR(ureq)) {
QETH_CARD_TEXT(card, 2, "snmpnome");
@@ -5096,7 +5100,7 @@ void qeth_dbf_longtext(debug_info_t *id, int level, char *fmt, ...)
char dbf_txt_buf[32];
va_list args;
- if (level > id->level)
+ if (!debug_level_enabled(id, level))
return;
va_start(args, fmt);
vsnprintf(dbf_txt_buf, sizeof(dbf_txt_buf), fmt, args);
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index 132a905b6bdb..0ca64484cfa3 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -344,7 +344,7 @@ void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len,
/**
* zfcp_dbf_san_req - trace event for issued SAN request
- * @tag: indentifier for event
+ * @tag: identifier for event
* @fsf_req: request containing issued CT data
* d_id: destination ID
*/
@@ -361,7 +361,7 @@ void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id)
/**
* zfcp_dbf_san_res - trace event for received SAN request
- * @tag: indentifier for event
+ * @tag: identifier for event
* @fsf_req: request containing issued CT data
*/
void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf)
@@ -377,7 +377,7 @@ void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf)
/**
* zfcp_dbf_san_in_els - trace event for incoming ELS
- * @tag: indentifier for event
+ * @tag: identifier for event
* @fsf_req: request containing issued CT data
*/
void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf)
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index 3ac7a4b30dd9..0be3d48681ae 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -278,7 +278,7 @@ struct zfcp_dbf {
static inline
void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
{
- if (level <= req->adapter->dbf->hba->level)
+ if (debug_level_enabled(req->adapter->dbf->hba, level))
zfcp_dbf_hba_fsf_res(tag, req);
}
@@ -317,7 +317,7 @@ void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd,
struct zfcp_adapter *adapter = (struct zfcp_adapter *)
scmd->device->host->hostdata[0];
- if (level <= adapter->dbf->scsi->level)
+ if (debug_level_enabled(adapter->dbf->scsi, level))
zfcp_dbf_scsi(tag, scmd, req);
}