Skip to content

Commit b7f143d

Browse files
julianwiedmanndavem330
authored andcommitted
s390/qdio: implement IQD Multi-Write
This allows IQD drivers to send out multiple SBALs with a single SIGA instruction. Signed-off-by: Julian Wiedmann <[email protected]> Reviewed-by: Alexandra Winter <[email protected]> Acked-by: Heiko Carstens <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 4a956bd commit b7f143d

File tree

2 files changed

+16
-16
lines changed

2 files changed

+16
-16
lines changed

drivers/s390/cio/qdio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ enum qdio_irq_states {
8282
#define QDIO_SIGA_WRITE 0x00
8383
#define QDIO_SIGA_READ 0x01
8484
#define QDIO_SIGA_SYNC 0x02
85+
#define QDIO_SIGA_WRITEM 0x03
8586
#define QDIO_SIGA_WRITEQ 0x04
8687
#define QDIO_SIGA_QEBSM_FLAG 0x80
8788

drivers/s390/cio/qdio_main.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -310,26 +310,27 @@ static inline int qdio_siga_sync_q(struct qdio_q *q)
310310
return qdio_siga_sync(q, q->mask, 0);
311311
}
312312

313-
static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit,
314-
unsigned long aob)
313+
static int qdio_siga_output(struct qdio_q *q, unsigned int count,
314+
unsigned int *busy_bit, unsigned long aob)
315315
{
316316
unsigned long schid = *((u32 *) &q->irq_ptr->schid);
317317
unsigned int fc = QDIO_SIGA_WRITE;
318318
u64 start_time = 0;
319319
int retries = 0, cc;
320-
unsigned long laob = 0;
321320

322-
if (aob) {
323-
fc = QDIO_SIGA_WRITEQ;
324-
laob = aob;
321+
if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q)) {
322+
if (count > 1)
323+
fc = QDIO_SIGA_WRITEM;
324+
else if (aob)
325+
fc = QDIO_SIGA_WRITEQ;
325326
}
326327

327328
if (is_qebsm(q)) {
328329
schid = q->irq_ptr->sch_token;
329330
fc |= QDIO_SIGA_QEBSM_FLAG;
330331
}
331332
again:
332-
cc = do_siga_output(schid, q->mask, busy_bit, fc, laob);
333+
cc = do_siga_output(schid, q->mask, busy_bit, fc, aob);
333334

334335
/* hipersocket busy condition */
335336
if (unlikely(*busy_bit)) {
@@ -781,7 +782,8 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q, unsigned int start)
781782
return count;
782783
}
783784

784-
static int qdio_kick_outbound_q(struct qdio_q *q, unsigned long aob)
785+
static int qdio_kick_outbound_q(struct qdio_q *q, unsigned int count,
786+
unsigned long aob)
785787
{
786788
int retries = 0, cc;
787789
unsigned int busy_bit;
@@ -793,7 +795,7 @@ static int qdio_kick_outbound_q(struct qdio_q *q, unsigned long aob)
793795
retry:
794796
qperf_inc(q, siga_write);
795797

796-
cc = qdio_siga_output(q, &busy_bit, aob);
798+
cc = qdio_siga_output(q, count, &busy_bit, aob);
797799
switch (cc) {
798800
case 0:
799801
break;
@@ -1526,7 +1528,7 @@ static int handle_inbound(struct qdio_q *q, unsigned int callflags,
15261528
* @count: how many buffers are filled
15271529
*/
15281530
static int handle_outbound(struct qdio_q *q, unsigned int callflags,
1529-
int bufnr, int count)
1531+
unsigned int bufnr, unsigned int count)
15301532
{
15311533
const unsigned int scan_threshold = q->irq_ptr->scan_threshold;
15321534
unsigned char state = 0;
@@ -1549,13 +1551,10 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
15491551
if (queue_type(q) == QDIO_IQDIO_QFMT) {
15501552
unsigned long phys_aob = 0;
15511553

1552-
/* One SIGA-W per buffer required for unicast HSI */
1553-
WARN_ON_ONCE(count > 1 && !multicast_outbound(q));
1554-
1555-
if (q->u.out.use_cq)
1554+
if (q->u.out.use_cq && count == 1)
15561555
phys_aob = qdio_aob_for_buffer(&q->u.out, bufnr);
15571556

1558-
rc = qdio_kick_outbound_q(q, phys_aob);
1557+
rc = qdio_kick_outbound_q(q, count, phys_aob);
15591558
} else if (need_siga_sync(q)) {
15601559
rc = qdio_siga_sync_q(q);
15611560
} else if (count < QDIO_MAX_BUFFERS_PER_Q &&
@@ -1564,7 +1563,7 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
15641563
/* The previous buffer is not processed yet, tack on. */
15651564
qperf_inc(q, fast_requeue);
15661565
} else {
1567-
rc = qdio_kick_outbound_q(q, 0);
1566+
rc = qdio_kick_outbound_q(q, count, 0);
15681567
}
15691568

15701569
/* Let drivers implement their own completion scanning: */

0 commit comments

Comments
 (0)