aboutsummaryrefslogtreecommitdiff
path: root/drivers/s390/cio
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r--drivers/s390/cio/cio.c25
-rw-r--r--drivers/s390/cio/css.c3
-rw-r--r--drivers/s390/cio/qdio.c13
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;