<div dir="ltr"><div dir="ltr"><div>From: Julian Wiedmann <<a href="mailto:jwi@linux.ibm.com">jwi@linux.ibm.com</a>></div><div><br></div><div>BugLink: <a href="http://bugs.launchpad.net/bugs/1801686">http://bugs.launchpad.net/bugs/1801686</a></div><div><br></div><div>s390/qdio: reset old sbal_state flags</div><div>    </div><div>When allocating a new AOB fails, handle_outbound() is still capable of</div><div>transmitting the selected buffer (just without async completion).</div><div>    </div><div>But if a previous transfer on this queue slot used async completion, its</div><div>sbal_state flags field is still set to QDIO_OUTBUF_STATE_FLAG_PENDING.</div><div>So when the upper layer driver sees this stale flag, it expects an async</div><div>completion that never happens.</div><div>    </div><div>Fix this by unconditionally clearing the flags field.</div><div>    </div><div>Fixes: 104ea556ee7f ("qdio: support asynchronous delivery of storage blocks")</div><div>Cc: <<a href="mailto:stable@vger.kernel.org">stable@vger.kernel.org</a>> #v3.2+</div><div>Signed-off-by: Julian Wiedmann <<a href="mailto:jwi@linux.ibm.com">jwi@linux.ibm.com</a>></div><div>Signed-off-by: Martin Schwidefsky <<a href="mailto:schwidefsky@de.ibm.com">schwidefsky@de.ibm.com</a>></div><div>(cherry picked from commit 64e03ff72623b8c2ea89ca3cb660094e019ed4ae)</div><div>Signed-off-by: Frank Heimes <<a href="mailto:frank.heimes@canonical.com">frank.heimes@canonical.com</a>></div><div><br></div><div>---</div><div><br></div><div>diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h</div><div>index de11ecc..9c9970a 100644</div><div>--- a/arch/s390/include/asm/qdio.h</div><div>+++ b/arch/s390/include/asm/qdio.h</div><div>@@ -262,7 +262,6 @@ struct qdio_outbuf_state {</div><div>        void *user;</div><div> };</div><div> </div><div>-#define QDIO_OUTBUF_STATE_FLAG_NONE    0x00</div><div> #define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01</div><div> </div><div> #define CHSC_AC1_INITIATE_INPUTQ       0x80</div><div>diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c</div><div>index f4ca72d..9c7d9da 100644</div><div>--- a/drivers/s390/cio/qdio_main.c</div><div>+++ b/drivers/s390/cio/qdio_main.c</div><div>@@ -631,21 +631,20 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,</div><div>        unsigned long phys_aob = 0;</div><div> </div><div>        if (!q->use_cq)</div><div>-               goto out;</div><div>+               return 0;</div><div> </div><div>        if (!q->aobs[bufnr]) {</div><div>                struct qaob *aob = qdio_allocate_aob();</div><div>                q->aobs[bufnr] = aob;</div><div>        }</div><div>        if (q->aobs[bufnr]) {</div><div>-               q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE;</div><div>                q->sbal_state[bufnr].aob = q->aobs[bufnr];</div><div>                q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user;</div><div>                phys_aob = virt_to_phys(q->aobs[bufnr]);</div><div>                WARN_ON_ONCE(phys_aob & 0xFF);</div><div>        }</div><div> </div><div>-out:</div><div>+       q->sbal_state[bufnr].flags = 0;</div><div>        return phys_aob;</div><div> }</div><div><br></div></div></div>