diff options
Diffstat (limited to 'drivers/s390/char')
-rw-r--r-- | drivers/s390/char/con3215.c | 9 | ||||
-rw-r--r-- | drivers/s390/char/sclp.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cmd.c | 6 | ||||
-rw-r--r-- | drivers/s390/char/sclp_quiesce.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/sclp_sdias.c | 101 | ||||
-rw-r--r-- | drivers/s390/char/sclp_tty.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/tty3270.c | 1 | ||||
-rw-r--r-- | drivers/s390/char/vmur.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/zcore.c | 1 |
10 files changed, 88 insertions, 39 deletions
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index e71a50d4b221..4f9f1dcc1551 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c @@ -933,13 +933,9 @@ console_initcall(con3215_init); static int tty3215_open(struct tty_struct *tty, struct file * filp) { struct raw3215_info *raw; - int retval, line; + int retval; - line = tty->index; - if ((line < 0) || (line >= NR_3215)) - return -ENODEV; - - raw = raw3215[line]; + raw = raw3215[tty->index]; if (raw == NULL) return -ENODEV; @@ -1145,7 +1141,6 @@ static int __init tty3215_init(void) * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc */ - driver->owner = THIS_MODULE; driver->driver_name = "tty3215"; driver->name = "ttyS"; driver->major = TTY_MAJOR; diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index eaa7e78186f9..30f29a0020a1 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -393,7 +393,7 @@ __sclp_find_req(u32 sccb) /* Handler for external interruption. Perform request post-processing. * Prepare read event data request if necessary. Start processing of next * request on queue. */ -static void sclp_interrupt_handler(unsigned int ext_int_code, +static void sclp_interrupt_handler(struct ext_code ext_code, unsigned int param32, unsigned long param64) { struct sclp_req *req; @@ -818,7 +818,7 @@ EXPORT_SYMBOL(sclp_reactivate); /* Handler for external interruption used during initialization. Modify * request state to done. */ -static void sclp_check_handler(unsigned int ext_int_code, +static void sclp_check_handler(struct ext_code ext_code, unsigned int param32, unsigned long param64) { u32 finished_sccb; diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 0b54a91f8dcd..231a1d85127b 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -21,6 +21,7 @@ #include <asm/chpid.h> #include <asm/sclp.h> #include <asm/setup.h> +#include <asm/ctl_reg.h> #include "sclp.h" @@ -441,9 +442,8 @@ static int sclp_mem_notifier(struct notifier_block *nb, start = arg->start_pfn << PAGE_SHIFT; size = arg->nr_pages << PAGE_SHIFT; mutex_lock(&sclp_mem_mutex); - for (id = 0; id <= sclp_max_storage_id; id++) - if (!test_bit(id, sclp_storage_ids)) - sclp_attach_storage(id); + for_each_clear_bit(id, sclp_storage_ids, sclp_max_storage_id + 1) + sclp_attach_storage(id); switch (action) { case MEM_ONLINE: case MEM_GOING_OFFLINE: diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c index 87fc0ac11e67..69df137310bc 100644 --- a/drivers/s390/char/sclp_quiesce.c +++ b/drivers/s390/char/sclp_quiesce.c @@ -15,7 +15,6 @@ #include <linux/reboot.h> #include <linux/atomic.h> #include <asm/ptrace.h> -#include <asm/sigp.h> #include <asm/smp.h> #include "sclp.h" diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c index fa733ecd3d70..69e6c50d4cfb 100644 --- a/drivers/s390/char/sclp_sdias.c +++ b/drivers/s390/char/sclp_sdias.c @@ -8,6 +8,7 @@ #define KMSG_COMPONENT "sclp_sdias" #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt +#include <linux/completion.h> #include <linux/sched.h> #include <asm/sclp.h> #include <asm/debug.h> @@ -62,15 +63,29 @@ struct sdias_sccb { } __attribute__((packed)); static struct sdias_sccb sccb __attribute__((aligned(4096))); +static struct sdias_evbuf sdias_evbuf; -static int sclp_req_done; -static wait_queue_head_t sdias_wq; +static DECLARE_COMPLETION(evbuf_accepted); +static DECLARE_COMPLETION(evbuf_done); static DEFINE_MUTEX(sdias_mutex); +/* + * Called by SCLP base when read event data has been completed (async mode only) + */ +static void sclp_sdias_receiver_fn(struct evbuf_header *evbuf) +{ + memcpy(&sdias_evbuf, evbuf, + min_t(unsigned long, sizeof(sdias_evbuf), evbuf->length)); + complete(&evbuf_done); + TRACE("sclp_sdias_receiver_fn done\n"); +} + +/* + * Called by SCLP base when sdias event has been accepted + */ static void sdias_callback(struct sclp_req *request, void *data) { - sclp_req_done = 1; - wake_up(&sdias_wq); /* Inform caller, that request is complete */ + complete(&evbuf_accepted); TRACE("callback done\n"); } @@ -80,7 +95,6 @@ static int sdias_sclp_send(struct sclp_req *req) int rc; for (retries = SDIAS_RETRIES; retries; retries--) { - sclp_req_done = 0; TRACE("add request\n"); rc = sclp_add_request(req); if (rc) { @@ -91,16 +105,31 @@ static int sdias_sclp_send(struct sclp_req *req) continue; } /* initiated, wait for completion of service call */ - wait_event(sdias_wq, (sclp_req_done == 1)); + wait_for_completion(&evbuf_accepted); if (req->status == SCLP_REQ_FAILED) { TRACE("sclp request failed\n"); - rc = -EIO; continue; } + /* if not accepted, retry */ + if (!(sccb.evbuf.hdr.flags & 0x80)) { + TRACE("sclp request failed: flags=%x\n", + sccb.evbuf.hdr.flags); + continue; + } + /* + * for the sync interface the response is in the initial sccb + */ + if (!sclp_sdias_register.receiver_fn) { + memcpy(&sdias_evbuf, &sccb.evbuf, sizeof(sdias_evbuf)); + TRACE("sync request done\n"); + return 0; + } + /* otherwise we wait for completion */ + wait_for_completion(&evbuf_done); TRACE("request done\n"); - break; + return 0; } - return rc; + return -EIO; } /* @@ -140,13 +169,12 @@ int sclp_sdias_blk_count(void) goto out; } - switch (sccb.evbuf.event_status) { + switch (sdias_evbuf.event_status) { case 0: - rc = sccb.evbuf.blk_cnt; + rc = sdias_evbuf.blk_cnt; break; default: - pr_err("SCLP error: %x\n", - sccb.evbuf.event_status); + pr_err("SCLP error: %x\n", sdias_evbuf.event_status); rc = -EIO; goto out; } @@ -211,18 +239,18 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks) goto out; } - switch (sccb.evbuf.event_status) { + switch (sdias_evbuf.event_status) { case EVSTATE_ALL_STORED: TRACE("all stored\n"); case EVSTATE_PART_STORED: - TRACE("part stored: %i\n", sccb.evbuf.blk_cnt); + TRACE("part stored: %i\n", sdias_evbuf.blk_cnt); break; case EVSTATE_NO_DATA: TRACE("no data\n"); default: pr_err("Error from SCLP while copying hsa. " "Event status = %x\n", - sccb.evbuf.event_status); + sdias_evbuf.event_status); rc = -EIO; } out: @@ -230,19 +258,50 @@ out: return rc; } -int __init sclp_sdias_init(void) +static int __init sclp_sdias_register_check(void) { int rc; + rc = sclp_register(&sclp_sdias_register); + if (rc) + return rc; + if (sclp_sdias_blk_count() == 0) { + sclp_unregister(&sclp_sdias_register); + return -ENODEV; + } + return 0; +} + +static int __init sclp_sdias_init_sync(void) +{ + TRACE("Try synchronous mode\n"); + sclp_sdias_register.receive_mask = 0; + sclp_sdias_register.receiver_fn = NULL; + return sclp_sdias_register_check(); +} + +static int __init sclp_sdias_init_async(void) +{ + TRACE("Try asynchronous mode\n"); + sclp_sdias_register.receive_mask = EVTYP_SDIAS_MASK; + sclp_sdias_register.receiver_fn = sclp_sdias_receiver_fn; + return sclp_sdias_register_check(); +} + +int __init sclp_sdias_init(void) +{ if (ipl_info.type != IPL_TYPE_FCP_DUMP) return 0; sdias_dbf = debug_register("dump_sdias", 4, 1, 4 * sizeof(long)); debug_register_view(sdias_dbf, &debug_sprintf_view); debug_set_level(sdias_dbf, 6); - rc = sclp_register(&sclp_sdias_register); - if (rc) - return rc; - init_waitqueue_head(&sdias_wq); + if (sclp_sdias_init_sync() == 0) + goto out; + if (sclp_sdias_init_async() == 0) + goto out; + TRACE("init failed\n"); + return -ENODEV; +out: TRACE("init done\n"); return 0; } diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index a879c139926a..40a9d69c898e 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -551,7 +551,6 @@ sclp_tty_init(void) return rc; } - driver->owner = THIS_MODULE; driver->driver_name = "sclp_line"; driver->name = "sclp_line"; driver->major = TTY_MAJOR; diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index 5d706e6c946f..b635472ae660 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -685,7 +685,6 @@ static int __init sclp_vt220_tty_init(void) if (rc) goto out_driver; - driver->owner = THIS_MODULE; driver->driver_name = SCLP_VT220_DRIVER_NAME; driver->name = SCLP_VT220_DEVICE_NAME; driver->major = SCLP_VT220_MAJOR; diff --git a/drivers/s390/char/tty3270.c b/drivers/s390/char/tty3270.c index 2db1482b406e..b43445a55cb6 100644 --- a/drivers/s390/char/tty3270.c +++ b/drivers/s390/char/tty3270.c @@ -1784,7 +1784,6 @@ static int __init tty3270_init(void) * Entries in tty3270_driver that are NOT initialized: * proc_entry, set_termios, flush_buffer, set_ldisc, write_proc */ - driver->owner = THIS_MODULE; driver->driver_name = "ttyTUB"; driver->name = "ttyTUB"; driver->major = IBM_TTY3270_MAJOR; diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 85f4a9a5d12e..73bef0bd394c 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -903,7 +903,7 @@ static int ur_set_online(struct ccw_device *cdev) goto fail_urdev_put; } - cdev_init(urd->char_device, &ur_fops); + urd->char_device->ops = &ur_fops; urd->char_device->dev = MKDEV(major, minor); urd->char_device->owner = ur_fops.owner; diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 1b6d9247fdc7..3303d66b2794 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -21,7 +21,6 @@ #include <asm/ipl.h> #include <asm/sclp.h> #include <asm/setup.h> -#include <asm/sigp.h> #include <asm/uaccess.h> #include <asm/debug.h> #include <asm/processor.h> |