s390/qdio: restrict QAOB usage to IQD unicast queues
authorJulian Wiedmann <jwi@linux.ibm.com>
Mon, 1 Jul 2019 12:19:29 +0000 (14:19 +0200)
committerHeiko Carstens <heiko.carstens@de.ibm.com>
Tue, 23 Jul 2019 08:44:03 +0000 (10:44 +0200)
The IQD mcast queue doesn't support QAOB mode, so skip the
qdio_enable_async_operation() setup call for this queue. This avoids
the allocation of an unneeded QAOB pointer array, and sets up q->use_cq
properly so that drivers are prohibited from using QAOBs for mcast
traffic.

Take this opportunity to streamline the q->use_cq and aob != 0 checks.
The path to qdio_siga_output() is straight-forward, we don't need to
worry about being called with bad operands.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
drivers/s390/cio/qdio_main.c

index 7f5adf02f09596b13a58eef8184bc66c08590350..4142c85e77d8baa37d7def40b88c35c48e82bd70 100644 (file)
@@ -319,9 +319,7 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit,
        int retries = 0, cc;
        unsigned long laob = 0;
 
-       WARN_ON_ONCE(aob && ((queue_type(q) != QDIO_IQDIO_QFMT) ||
-                            !q->u.out.use_cq));
-       if (q->u.out.use_cq && aob != 0) {
+       if (aob) {
                fc = QDIO_SIGA_WRITEQ;
                laob = aob;
        }
@@ -621,9 +619,6 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
 {
        unsigned long phys_aob = 0;
 
-       if (!q->use_cq)
-               return 0;
-
        if (!q->aobs[bufnr]) {
                struct qaob *aob = qdio_allocate_aob();
                q->aobs[bufnr] = aob;
@@ -1308,6 +1303,8 @@ static void qdio_detect_hsicq(struct qdio_irq *irq_ptr)
 
        for_each_output_queue(irq_ptr, q, i) {
                if (use_cq) {
+                       if (multicast_outbound(q))
+                               continue;
                        if (qdio_enable_async_operation(&q->u.out) < 0) {
                                use_cq = 0;
                                continue;
@@ -1553,7 +1550,8 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
                /* One SIGA-W per buffer required for unicast HSI */
                WARN_ON_ONCE(count > 1 && !multicast_outbound(q));
 
-               phys_aob = qdio_aob_for_buffer(&q->u.out, bufnr);
+               if (q->u.out.use_cq)
+                       phys_aob = qdio_aob_for_buffer(&q->u.out, bufnr);
 
                rc = qdio_kick_outbound_q(q, phys_aob);
        } else if (need_siga_sync(q)) {