diff options
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/cio.c | 25 | ||||
-rw-r--r-- | drivers/s390/cio/css.c | 3 | ||||
-rw-r--r-- | drivers/s390/cio/qdio.c | 13 |
3 files changed, 33 insertions, 8 deletions
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 7835a714a405..3a403f195cf8 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -871,11 +871,32 @@ __clear_subchannel_easy(struct subchannel_id schid) return -EBUSY; } +static int pgm_check_occured; + +static void cio_reset_pgm_check_handler(void) +{ + pgm_check_occured = 1; +} + +static int stsch_reset(struct subchannel_id schid, volatile struct schib *addr) +{ + int rc; + + pgm_check_occured = 0; + s390_reset_pgm_handler = cio_reset_pgm_check_handler; + rc = stsch(schid, addr); + s390_reset_pgm_handler = NULL; + if (pgm_check_occured) + return -EIO; + else + return rc; +} + static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) { struct schib schib; - if (stsch_err(schid, &schib)) + if (stsch_reset(schid, &schib)) return -ENXIO; if (!schib.pmcw.ena) return 0; @@ -972,7 +993,7 @@ static int __reipl_subchannel_match(struct subchannel_id schid, void *data) struct schib schib; struct sch_match_id *match_id = data; - if (stsch_err(schid, &schib)) + if (stsch_reset(schid, &schib)) return -ENXIO; if (schib.pmcw.dnv && (schib.pmcw.dev == match_id->devid.devno) && diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 4c81d890791e..9d6c02446863 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -139,6 +139,8 @@ css_register_subchannel(struct subchannel *sch) sch->dev.release = &css_subchannel_release; sch->dev.groups = subch_attr_groups; + css_get_ssd_info(sch); + /* make it known to the system */ ret = css_sch_device_register(sch); if (ret) { @@ -146,7 +148,6 @@ css_register_subchannel(struct subchannel *sch) __func__, sch->dev.bus_id); return ret; } - css_get_ssd_info(sch); return ret; } diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 9d4ea449a608..6fd1940842eb 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -979,12 +979,11 @@ __qdio_outbound_processing(struct qdio_q *q) if (q->is_iqdio_q) { /* - * for asynchronous queues, we better check, if the fill - * level is too high. for synchronous queues, the fill - * level will never be that high. + * for asynchronous queues, we better check, if the sent + * buffer is already switched from PRIMED to EMPTY. */ - if (atomic_read(&q->number_of_buffers_used)> - IQDIO_FILL_LEVEL_TO_POLL) + if ((q->queue_type == QDIO_IQDIO_QFMT_ASYNCH) && + !qdio_is_outbound_q_done(q)) qdio_mark_q(q); } else if (!q->hydra_gives_outbound_pcis) @@ -1825,6 +1824,10 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev, q->sbal[j]=*(outbound_sbals_array++); q->queue_type=q_format; + if ((q->queue_type == QDIO_IQDIO_QFMT) && + (no_output_qs > 1) && + (i == no_output_qs-1)) + q->queue_type = QDIO_IQDIO_QFMT_ASYNCH; q->int_parm=int_parm; q->is_input_q=0; q->schid = irq_ptr->schid; |