Commit 75443f02 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by Kleber Sacilotto de Souza

s390/qdio: reset old sbal_state flags

BugLink: https://bugs.launchpad.net/bugs/1792392

commit 64e03ff7 upstream.

When allocating a new AOB fails, handle_outbound() is still capable of
transmitting the selected buffer (just without async completion).

But if a previous transfer on this queue slot used async completion, its
sbal_state flags field is still set to QDIO_OUTBUF_STATE_FLAG_PENDING.
So when the upper layer driver sees this stale flag, it expects an async
completion that never happens.

Fix this by unconditionally clearing the flags field.

Fixes: 104ea556 ("qdio: support asynchronous delivery of storage blocks")
Cc: <stable@vger.kernel.org> #v3.2+
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
Signed-off-by: default avatarKleber Sacilotto de Souza <kleber.souza@canonical.com>
parent 49a97f99
...@@ -261,7 +261,6 @@ struct qdio_outbuf_state { ...@@ -261,7 +261,6 @@ struct qdio_outbuf_state {
void *user; void *user;
}; };
#define QDIO_OUTBUF_STATE_FLAG_NONE 0x00
#define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01 #define QDIO_OUTBUF_STATE_FLAG_PENDING 0x01
#define CHSC_AC1_INITIATE_INPUTQ 0x80 #define CHSC_AC1_INITIATE_INPUTQ 0x80
......
...@@ -640,21 +640,20 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q, ...@@ -640,21 +640,20 @@ static inline unsigned long qdio_aob_for_buffer(struct qdio_output_q *q,
unsigned long phys_aob = 0; unsigned long phys_aob = 0;
if (!q->use_cq) if (!q->use_cq)
goto out; return 0;
if (!q->aobs[bufnr]) { if (!q->aobs[bufnr]) {
struct qaob *aob = qdio_allocate_aob(); struct qaob *aob = qdio_allocate_aob();
q->aobs[bufnr] = aob; q->aobs[bufnr] = aob;
} }
if (q->aobs[bufnr]) { if (q->aobs[bufnr]) {
q->sbal_state[bufnr].flags = QDIO_OUTBUF_STATE_FLAG_NONE;
q->sbal_state[bufnr].aob = q->aobs[bufnr]; q->sbal_state[bufnr].aob = q->aobs[bufnr];
q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user; q->aobs[bufnr]->user1 = (u64) q->sbal_state[bufnr].user;
phys_aob = virt_to_phys(q->aobs[bufnr]); phys_aob = virt_to_phys(q->aobs[bufnr]);
WARN_ON_ONCE(phys_aob & 0xFF); WARN_ON_ONCE(phys_aob & 0xFF);
} }
out: q->sbal_state[bufnr].flags = 0;
return phys_aob; return phys_aob;
} }
......
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