Commit 65e4f776 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by Martin Schwidefsky

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: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: default avatarJens Remus <jremus@linux.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent b39544c6
...@@ -636,17 +636,13 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q, ...@@ -636,17 +636,13 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
return phys_aob; 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 start = q->first_to_kick;
int end = q->first_to_check;
int count;
if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)) if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
return; return;
count = sub_buf(end, start);
if (q->is_input_q) { if (q->is_input_q) {
qperf_inc(q, inbound_handler); qperf_inc(q, inbound_handler);
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count); 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) ...@@ -662,7 +658,7 @@ static void qdio_kick_handler(struct qdio_q *q)
q->irq_ptr->int_parm); q->irq_ptr->int_parm);
/* for the next time */ /* for the next time */
q->first_to_kick = end; q->first_to_kick = add_buf(start, count);
q->qdio_error = 0; q->qdio_error = 0;
} }
...@@ -685,7 +681,7 @@ static void __qdio_inbound_processing(struct qdio_q *q) ...@@ -685,7 +681,7 @@ static void __qdio_inbound_processing(struct qdio_q *q)
if (count == 0) if (count == 0)
return; return;
qdio_kick_handler(q); qdio_kick_handler(q, count);
if (!qdio_inbound_q_done(q)) { if (!qdio_inbound_q_done(q)) {
/* means poll time is not yet over */ /* means poll time is not yet over */
...@@ -843,7 +839,7 @@ static void __qdio_outbound_processing(struct qdio_q *q) ...@@ -843,7 +839,7 @@ static void __qdio_outbound_processing(struct qdio_q *q)
count = qdio_outbound_q_moved(q); count = qdio_outbound_q_moved(q);
if (count) if (count)
qdio_kick_handler(q); qdio_kick_handler(q, count);
if (queue_type(q) == QDIO_ZFCP_QFMT && !pci_out_supported(q->irq_ptr) && if (queue_type(q) == QDIO_ZFCP_QFMT && !pci_out_supported(q->irq_ptr) &&
!qdio_outbound_q_done(q)) !qdio_outbound_q_done(q))
...@@ -911,7 +907,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q) ...@@ -911,7 +907,7 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
if (count == 0) if (count == 0)
return; return;
qdio_kick_handler(q); qdio_kick_handler(q, count);
if (!qdio_inbound_q_done(q)) { if (!qdio_inbound_q_done(q)) {
qperf_inc(q, tasklet_inbound_resched); qperf_inc(q, tasklet_inbound_resched);
...@@ -1674,7 +1670,6 @@ int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr, ...@@ -1674,7 +1670,6 @@ int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr,
int *error) int *error)
{ {
struct qdio_q *q; struct qdio_q *q;
int start, end;
struct qdio_irq *irq_ptr = cdev->private->qdio_data; struct qdio_irq *irq_ptr = cdev->private->qdio_data;
int count; int count;
...@@ -1699,15 +1694,14 @@ int qdio_get_next_buffers(struct ccw_device *cdev, int nr, int *bufnr, ...@@ -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)) if (unlikely(q->irq_ptr->state != QDIO_IRQ_STATE_ACTIVE))
return -EIO; return -EIO;
start = q->first_to_kick; *bufnr = q->first_to_kick;
end = q->first_to_check;
*bufnr = start;
*error = q->qdio_error; *error = q->qdio_error;
/* for the next time */ /* for the next time */
q->first_to_kick = end; q->first_to_kick = add_buf(q->first_to_kick, count);
q->qdio_error = 0; q->qdio_error = 0;
return sub_buf(end, start);
return count;
} }
EXPORT_SYMBOL(qdio_get_next_buffers); EXPORT_SYMBOL(qdio_get_next_buffers);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment