s390/qdio: improve handling of PENDING buffers for QEBSM devices
For QEBSM devices the 'merge_pending' mechanism in get_buf_states() doesn't apply, and we can actually get SLSB_P_OUTPUT_PENDING returned. So for this case propagating the PENDING state to the driver via the queue's sbal_state doesn't make sense and creates unnecessary overhead. Instead introduce a new QDIO_ERROR_* flag that gets passed to the driver, and triggers the same processing as if the buffers were flagged as QDIO_OUTBUF_STATE_FLAG_PENDING. Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> Reviewed-by: Benjamin Block <bblock@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
540936df44
commit
7940eaf2e9
@ -315,6 +315,7 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
|
||||
#define QDIO_ERROR_GET_BUF_STATE 0x0002
|
||||
#define QDIO_ERROR_SET_BUF_STATE 0x0004
|
||||
#define QDIO_ERROR_SLSB_STATE 0x0100
|
||||
#define QDIO_ERROR_SLSB_PENDING 0x0200
|
||||
|
||||
#define QDIO_ERROR_FATAL 0x00ff
|
||||
#define QDIO_ERROR_TEMPORARY 0xff00
|
||||
|
@ -571,6 +571,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
|
||||
unsigned int *error)
|
||||
{
|
||||
unsigned char state = 0;
|
||||
unsigned int i;
|
||||
int count;
|
||||
|
||||
q->timestamp = get_tod_clock_fast();
|
||||
@ -591,8 +592,14 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
|
||||
return 0;
|
||||
|
||||
switch (state) {
|
||||
case SLSB_P_OUTPUT_EMPTY:
|
||||
case SLSB_P_OUTPUT_PENDING:
|
||||
/* detach the utilized QAOBs: */
|
||||
for (i = 0; i < count; i++)
|
||||
q->u.out.aobs[QDIO_BUFNR(start + i)] = NULL;
|
||||
|
||||
*error = QDIO_ERROR_SLSB_PENDING;
|
||||
fallthrough;
|
||||
case SLSB_P_OUTPUT_EMPTY:
|
||||
/* the adapter got it */
|
||||
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr,
|
||||
"out empty:%1d %02x", q->nr, count);
|
||||
@ -643,7 +650,7 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q, unsigned int start,
|
||||
if (count) {
|
||||
DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
|
||||
|
||||
if (q->u.out.use_cq) {
|
||||
if (q->u.out.use_cq && *error != QDIO_ERROR_SLSB_PENDING) {
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
|
@ -6068,14 +6068,17 @@ int qeth_poll(struct napi_struct *napi, int budget)
|
||||
EXPORT_SYMBOL_GPL(qeth_poll);
|
||||
|
||||
static void qeth_iqd_tx_complete(struct qeth_qdio_out_q *queue,
|
||||
unsigned int bidx, bool error, int budget)
|
||||
unsigned int bidx, unsigned int qdio_error,
|
||||
int budget)
|
||||
{
|
||||
struct qeth_qdio_out_buffer *buffer = queue->bufs[bidx];
|
||||
u8 sflags = buffer->buffer->element[15].sflags;
|
||||
struct qeth_card *card = queue->card;
|
||||
bool error = !!qdio_error;
|
||||
|
||||
if (queue->bufstates && (queue->bufstates[bidx].flags &
|
||||
QDIO_OUTBUF_STATE_FLAG_PENDING)) {
|
||||
if ((qdio_error == QDIO_ERROR_SLSB_PENDING) ||
|
||||
(queue->bufstates && (queue->bufstates[bidx].flags &
|
||||
QDIO_OUTBUF_STATE_FLAG_PENDING))) {
|
||||
WARN_ON_ONCE(card->options.cq != QETH_CQ_ENABLED);
|
||||
|
||||
QETH_CARD_TEXT_(card, 5, "pel%u", bidx);
|
||||
|
Loading…
Reference in New Issue
Block a user