summaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio
diff options
context:
space:
mode:
authorJulian Wiedmann <jwi@linux.ibm.com>2019-03-28 10:43:46 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2019-04-10 17:47:25 +0200
commit65e4f776385ac5cab021ad8d992e851375305906 (patch)
tree566a4e829338583e5b3109bf9670af4f5e472958 /drivers/s390/cio
parents390/qdio: pass up count of ready-to-process SBALs (diff)
downloadlinux-65e4f776385ac5cab021ad8d992e851375305906.tar.xz
linux-65e4f776385ac5cab021ad8d992e851375305906.zip
s390/qdio: simplify SBAL range calculation
When passing a range of ready-to-process SBALs to the upper-layer driver, use the available 'count' instead of calculating the distance between the first_to_check and first_to_kick cursors. This simplifies the logic of the queue-scan path, and opens up the possibility of scanning all 128 SBALs in one go (as determining the reported count no longer requires wrap-around safe arithmetic on the queue's cursors). Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> Reviewed-by: Jens Remus <jremus@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r--drivers/s390/cio/qdio_main.c24
1 files changed, 9 insertions, 15 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 195f35256cc5..b6bc02efa0d0 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -636,17 +636,13 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
return phys_aob;
}
-static void qdio_kick_handler(struct qdio_q *q)
+static void qdio_kick_handler(struct qdio_q *q, unsigned int count)
{
int start = q->first_to_kick;
- int end = q->first_to_check;
- int count;
if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
return;
- count = sub_buf(end, start);
-
if (q->is_input_q) {
qperf_inc(q, inbound_handler);
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count);
@@ -662,7 +658,7 @@ static void qdio_kick_handler(struct qdio_q *q)
q->irq_ptr->int_parm);
/* for the next time */
- q->first_to_kick = end;
+ q->first_to_kick = add_buf(start, count);
q->qdio_error = 0;
}
@@ -685,7 +681,7 @@ static void __qdio_inbound_processing(struct qdio_q *q)
if (count == 0)
return;
- qdio_kick_handler(q);
+ qdio_kick_handler(q, count);
if (!qdio_inbound_q_done(q)) {
/* means poll time is not yet over */
@@ -843,7 +839,7 @@ static void __qdio_outbound_processing(struct qdio_q *q)
count = qdio_outbound_q_moved(q);
if (count)
- qdio_kick_handler(q);
+ qdio_kick_handler(q, count);
if (queue_type(q) == QDIO_ZFCP_QFMT && !pci_out_supported(q->irq_ptr) &&
!qdio_outbound_q_done(q))
@@ -911,7 +907,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
if (count == 0)
return;
- qdio_kick_handler(q);
+ qdio_kick_handler(q, count);
if (!qdio_inbound_q_done(q)) {
qperf_inc(q, tasklet_inbound_resched);
@@ -1674,7 +1670,6 @@ int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr,
int *error)
{
struct qdio_q *q;
- int start, end;
struct qdio_irq *irq_ptr = cdev->private->qdio_data;
int count;
@@ -1699,15 +1694,14 @@ int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr,
if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
return -EIO;
- start = q->first_to_kick;
- end = q->first_to_check;
- *bufnr = start;
+ *bufnr = q->first_to_kick;
*error = q->qdio_error;
/* for the next time */
- q->first_to_kick = end;
+ q->first_to_kick = add_buf(q->first_to_kick, count);
q->qdio_error = 0;
- return sub_buf(end, start);
+
+ return count;
}
EXPORT_SYMBOL(qdio_get_next_buffers);