diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/block/dasd.c | 12 | ||||
-rw-r--r-- | drivers/s390/block/dcssblk.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp.c | 12 | ||||
-rw-r--r-- | drivers/s390/char/sclp.h | 6 | ||||
-rw-r--r-- | drivers/s390/char/sclp_config.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_cpi_sys.c | 2 | ||||
-rw-r--r-- | drivers/s390/char/sclp_rw.c | 4 | ||||
-rw-r--r-- | drivers/s390/char/sclp_vt220.c | 2 | ||||
-rw-r--r-- | drivers/s390/cio/device.c | 15 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.c | 13 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.h | 2 |
11 files changed, 38 insertions, 34 deletions
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index d984e0f..ccf46c9 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c @@ -1149,12 +1149,14 @@ static void __dasd_device_process_final_queue(struct dasd_device *device, { struct list_head *l, *n; struct dasd_ccw_req *cqr; + struct dasd_block *block; list_for_each_safe(l, n, final_queue) { cqr = list_entry(l, struct dasd_ccw_req, devlist); list_del_init(&cqr->devlist); - if (cqr->block) - spin_lock_bh(&cqr->block->queue_lock); + block = cqr->block; + if (block) + spin_lock_bh(&block->queue_lock); switch (cqr->status) { case DASD_CQR_SUCCESS: cqr->status = DASD_CQR_DONE; @@ -1172,15 +1174,13 @@ static void __dasd_device_process_final_queue(struct dasd_device *device, cqr, cqr->status); BUG(); } - if (cqr->block) - spin_unlock_bh(&cqr->block->queue_lock); if (cqr->callback != NULL) (cqr->callback)(cqr, cqr->callback_data); + if (block) + spin_unlock_bh(&block->queue_lock); } } - - /* * Take a look at the first request on the ccw queue and check * if it reached its expire time. If so, terminate the IO. diff --git a/drivers/s390/block/dcssblk.c b/drivers/s390/block/dcssblk.c index 3faf053..e6c94db 100644 --- a/drivers/s390/block/dcssblk.c +++ b/drivers/s390/block/dcssblk.c @@ -666,7 +666,7 @@ dcssblk_make_request(struct request_queue *q, struct bio *bio) page_addr = (unsigned long) page_address(bvec->bv_page) + bvec->bv_offset; source_addr = dev_info->start + (index<<12) + bytes_done; - if (unlikely(page_addr & 4095) != 0 || (bvec->bv_len & 4095) != 0) + if (unlikely((page_addr & 4095) != 0) || (bvec->bv_len & 4095) != 0) // More paranoia. goto fail; if (bio_data_dir(bio) == READ) { diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index 25629b9..2c7a1ee 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c @@ -29,10 +29,10 @@ static ext_int_info_t ext_int_info_hwc; /* Lock to protect internal data consistency. */ static DEFINE_SPINLOCK(sclp_lock); -/* Mask of events that we can receive from the sclp interface. */ +/* Mask of events that we can send to the sclp interface. */ static sccb_mask_t sclp_receive_mask; -/* Mask of events that we can send to the sclp interface. */ +/* Mask of events that we can receive from the sclp interface. */ static sccb_mask_t sclp_send_mask; /* List of registered event listeners and senders. */ @@ -380,7 +380,7 @@ sclp_interrupt_handler(__u16 code) } sclp_running_state = sclp_running_state_idle; } - if (evbuf_pending && sclp_receive_mask != 0 && + if (evbuf_pending && sclp_activation_state == sclp_activation_state_active) __sclp_queue_read_req(); spin_unlock(&sclp_lock); @@ -459,8 +459,8 @@ sclp_dispatch_state_change(void) reg = NULL; list_for_each(l, &sclp_reg_list) { reg = list_entry(l, struct sclp_register, list); - receive_mask = reg->receive_mask & sclp_receive_mask; - send_mask = reg->send_mask & sclp_send_mask; + receive_mask = reg->send_mask & sclp_receive_mask; + send_mask = reg->receive_mask & sclp_send_mask; if (reg->sclp_receive_mask != receive_mask || reg->sclp_send_mask != send_mask) { reg->sclp_receive_mask = receive_mask; @@ -615,8 +615,8 @@ struct init_sccb { u16 mask_length; sccb_mask_t receive_mask; sccb_mask_t send_mask; - sccb_mask_t sclp_send_mask; sccb_mask_t sclp_receive_mask; + sccb_mask_t sclp_send_mask; } __attribute__((packed)); /* Prepare init mask request. Called while sclp_lock is locked. */ diff --git a/drivers/s390/char/sclp.h b/drivers/s390/char/sclp.h index aa8186d..bac80e8 100644 --- a/drivers/s390/char/sclp.h +++ b/drivers/s390/char/sclp.h @@ -122,11 +122,13 @@ struct sclp_req { /* of some routines it wants to be called from the low level driver */ struct sclp_register { struct list_head list; - /* event masks this user is registered for */ + /* User wants to receive: */ sccb_mask_t receive_mask; + /* User wants to send: */ sccb_mask_t send_mask; - /* actually present events */ + /* H/W can receive: */ sccb_mask_t sclp_receive_mask; + /* H/W can send: */ sccb_mask_t sclp_send_mask; /* called if event type availability changes */ void (*state_change_fn)(struct sclp_register *); diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index 9dc77f1..b8f35bc 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c @@ -64,7 +64,7 @@ static int __init sclp_conf_init(void) return rc; } - if (!(sclp_conf_register.sclp_receive_mask & EVTYP_CONFMGMDATA_MASK)) { + if (!(sclp_conf_register.sclp_send_mask & EVTYP_CONFMGMDATA_MASK)) { printk(KERN_WARNING TAG "no configuration management.\n"); sclp_unregister(&sclp_conf_register); rc = -ENOSYS; diff --git a/drivers/s390/char/sclp_cpi_sys.c b/drivers/s390/char/sclp_cpi_sys.c index 4161703..9f37456 100644 --- a/drivers/s390/char/sclp_cpi_sys.c +++ b/drivers/s390/char/sclp_cpi_sys.c @@ -129,7 +129,7 @@ static int cpi_req(void) "to hardware console.\n"); goto out; } - if (!(sclp_cpi_event.sclp_send_mask & EVTYP_CTLPROGIDENT_MASK)) { + if (!(sclp_cpi_event.sclp_receive_mask & EVTYP_CTLPROGIDENT_MASK)) { printk(KERN_WARNING "cpi: no control program " "identification support\n"); rc = -EOPNOTSUPP; diff --git a/drivers/s390/char/sclp_rw.c b/drivers/s390/char/sclp_rw.c index ad7195d..da09781 100644 --- a/drivers/s390/char/sclp_rw.c +++ b/drivers/s390/char/sclp_rw.c @@ -452,10 +452,10 @@ sclp_emit_buffer(struct sclp_buffer *buffer, return -EIO; sccb = buffer->sccb; - if (sclp_rw_event.sclp_send_mask & EVTYP_MSG_MASK) + if (sclp_rw_event.sclp_receive_mask & EVTYP_MSG_MASK) /* Use normal write message */ sccb->msg_buf.header.type = EVTYP_MSG; - else if (sclp_rw_event.sclp_send_mask & EVTYP_PMSGCMD_MASK) + else if (sclp_rw_event.sclp_receive_mask & EVTYP_PMSGCMD_MASK) /* Use write priority message */ sccb->msg_buf.header.type = EVTYP_PMSGCMD; else diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c index f47f4a7..92f5272 100644 --- a/drivers/s390/char/sclp_vt220.c +++ b/drivers/s390/char/sclp_vt220.c @@ -202,7 +202,7 @@ sclp_vt220_callback(struct sclp_req *request, void *data) static int __sclp_vt220_emit(struct sclp_vt220_request *request) { - if (!(sclp_vt220_register.sclp_send_mask & EVTYP_VT220MSG_MASK)) { + if (!(sclp_vt220_register.sclp_receive_mask & EVTYP_VT220MSG_MASK)) { request->sclp_req.status = SCLP_REQ_FAILED; return -EIO; } diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index d35dc3f..fec004f 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -32,7 +32,7 @@ #include "io_sch.h" static struct timer_list recovery_timer; -static spinlock_t recovery_lock; +static DEFINE_SPINLOCK(recovery_lock); static int recovery_phase; static const unsigned long recovery_delay[] = { 3, 30, 300 }; @@ -1535,7 +1535,7 @@ static int recovery_check(struct device *dev, void *data) return 0; } -static void recovery_func(unsigned long data) +static void recovery_work_func(struct work_struct *unused) { int redo = 0; @@ -1553,6 +1553,17 @@ static void recovery_func(unsigned long data) CIO_MSG_EVENT(2, "recovery: end\n"); } +static DECLARE_WORK(recovery_work, recovery_work_func); + +static void recovery_func(unsigned long data) +{ + /* + * We can't do our recovery in softirq context and it's not + * performance critical, so we schedule it. + */ + schedule_work(&recovery_work); +} + void ccw_device_schedule_recovery(void) { unsigned long flags; diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 097fc09..2b5bfb7 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -32,7 +32,7 @@ #include <linux/module.h> #include <linux/init.h> - +#include <linux/delay.h> #include <linux/slab.h> #include <linux/kernel.h> #include <linux/proc_fs.h> @@ -1215,9 +1215,6 @@ tiqdio_is_inbound_q_done(struct qdio_q *q) if (!no_used) return 1; - if (!q->siga_sync && !irq->is_qebsm) - /* we'll check for more primed buffers in qeth_stop_polling */ - return 0; if (irq->is_qebsm) { count = 1; start_buf = q->first_to_check; @@ -3332,13 +3329,7 @@ qdio_activate(struct ccw_device *cdev, int flags) } } - wait_event_interruptible_timeout(cdev->private->wait_q, - ((irq_ptr->state == - QDIO_IRQ_STATE_STOPPED) || - (irq_ptr->state == - QDIO_IRQ_STATE_ERR)), - QDIO_ACTIVATE_TIMEOUT); - + msleep(QDIO_ACTIVATE_TIMEOUT); switch (irq_ptr->state) { case QDIO_IRQ_STATE_STOPPED: case QDIO_IRQ_STATE_ERR: diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index 37870e4..da8a272 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h @@ -57,10 +57,10 @@ of the queue to 0 */ #define QDIO_ESTABLISH_TIMEOUT (1*HZ) -#define QDIO_ACTIVATE_TIMEOUT (5*HZ) #define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ) #define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ) #define QDIO_FORCE_CHECK_TIMEOUT (10*HZ) +#define QDIO_ACTIVATE_TIMEOUT (5) /* 5 ms */ enum qdio_irq_states { QDIO_IRQ_STATE_INACTIVE, |