Commit a60bffe5 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by Heiko Carstens
Browse files

s390/qdio: split do_QDIO()



The callers know what type of queue they want to work with. Introduce
type-specific variants to add buffers on an {Input,Output} queue, so
that we can avoid some function parameters and the de-muxing into
type-specific hot paths.

Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: default avatarBenjamin Block <bblock@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent b44995e5
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -336,9 +336,6 @@ struct qdio_initialize {
	struct qdio_buffer ***output_sbal_addr_array;
};

#define QDIO_FLAG_SYNC_INPUT		0x01
#define QDIO_FLAG_SYNC_OUTPUT		0x02

int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count);
void qdio_free_buffers(struct qdio_buffer **buf, unsigned int count);
void qdio_reset_buffers(struct qdio_buffer **buf, unsigned int count);
@@ -348,14 +345,18 @@ extern int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
extern int qdio_establish(struct ccw_device *cdev,
			  struct qdio_initialize *init_data);
extern int qdio_activate(struct ccw_device *);
extern int do_QDIO(struct ccw_device *cdev, unsigned int callflags, int q_nr,
		   unsigned int bufnr, unsigned int count, struct qaob *aob);
extern int qdio_start_irq(struct ccw_device *cdev);
extern int qdio_stop_irq(struct ccw_device *cdev);
extern int qdio_inspect_input_queue(struct ccw_device *cdev, unsigned int nr,
				    unsigned int *bufnr, unsigned int *error);
extern int qdio_inspect_output_queue(struct ccw_device *cdev, unsigned int nr,
				     unsigned int *bufnr, unsigned int *error);
extern int qdio_add_bufs_to_input_queue(struct ccw_device *cdev,
					unsigned int q_nr, unsigned int bufnr,
					unsigned int count);
extern int qdio_add_bufs_to_output_queue(struct ccw_device *cdev,
					 unsigned int q_nr, unsigned int bufnr,
					 unsigned int count, struct qaob *aob);
extern int qdio_shutdown(struct ccw_device *, int);
extern int qdio_free(struct ccw_device *);
extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *);
+38 −13
Original line number Diff line number Diff line
@@ -1214,6 +1214,35 @@ static int handle_inbound(struct qdio_q *q, int bufnr, int count)
	return 0;
}

/**
 * qdio_add_bufs_to_input_queue - process buffers on an Input Queue
 * @cdev: associated ccw_device for the qdio subchannel
 * @q_nr: queue number
 * @bufnr: buffer number
 * @count: how many buffers to process
 */
int qdio_add_bufs_to_input_queue(struct ccw_device *cdev, unsigned int q_nr,
				 unsigned int bufnr, unsigned int count)
{
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;

	if (bufnr >= QDIO_MAX_BUFFERS_PER_Q || count > QDIO_MAX_BUFFERS_PER_Q)
		return -EINVAL;

	if (!irq_ptr)
		return -ENODEV;

	DBF_DEV_EVENT(DBF_INFO, irq_ptr, "addi b:%02x c:%02x", bufnr, count);

	if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)
		return -EIO;
	if (!count)
		return 0;

	return handle_inbound(irq_ptr->input_qs[q_nr], bufnr, count);
}
EXPORT_SYMBOL_GPL(qdio_add_bufs_to_input_queue);

/**
 * handle_outbound - process filled outbound buffers
 * @q: queue containing the buffers
@@ -1255,16 +1284,16 @@ static int handle_outbound(struct qdio_q *q, unsigned int bufnr, unsigned int co
}

/**
 * do_QDIO - process input or output buffers
 * qdio_add_bufs_to_output_queue - process buffers on an Output Queue
 * @cdev: associated ccw_device for the qdio subchannel
 * @callflags: input or output and special flags from the program
 * @q_nr: queue number
 * @bufnr: buffer number
 * @count: how many buffers to process
 * @aob: asynchronous operation block (outbound only)
 * @aob: asynchronous operation block
 */
int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
	    int q_nr, unsigned int bufnr, unsigned int count, struct qaob *aob)
int qdio_add_bufs_to_output_queue(struct ccw_device *cdev, unsigned int q_nr,
				  unsigned int bufnr, unsigned int count,
				  struct qaob *aob)
{
	struct qdio_irq *irq_ptr = cdev->private->qdio_data;

@@ -1274,20 +1303,16 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
	if (!irq_ptr)
		return -ENODEV;

	DBF_DEV_EVENT(DBF_INFO, irq_ptr,
		      "do%02x b:%02x c:%02x", callflags, bufnr, count);
	DBF_DEV_EVENT(DBF_INFO, irq_ptr, "addo b:%02x c:%02x", bufnr, count);

	if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)
		return -EIO;
	if (!count)
		return 0;
	if (callflags & QDIO_FLAG_SYNC_INPUT)
		return handle_inbound(irq_ptr->input_qs[q_nr], bufnr, count);
	else if (callflags & QDIO_FLAG_SYNC_OUTPUT)

	return handle_outbound(irq_ptr->output_qs[q_nr], bufnr, count, aob);
	return -EINVAL;
}
EXPORT_SYMBOL_GPL(do_QDIO);
EXPORT_SYMBOL_GPL(qdio_add_bufs_to_output_queue);

/**
 * qdio_start_irq - enable interrupt processing for the device
+10 −10
Original line number Diff line number Diff line
@@ -355,8 +355,8 @@ static int qeth_cq_init(struct qeth_card *card)
		qdio_reset_buffers(card->qdio.c_q->qdio_bufs,
				   QDIO_MAX_BUFFERS_PER_Q);
		card->qdio.c_q->next_buf_to_init = 127;
		rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 1, 0, 127,
			     NULL);

		rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), 1, 0, 127);
		if (rc) {
			QETH_CARD_TEXT_(card, 2, "1err%d", rc);
			goto out;
@@ -2926,8 +2926,7 @@ static int qeth_init_qdio_queues(struct qeth_card *card)
	}

	card->qdio.in_q->next_buf_to_init = QDIO_BUFNR(rx_bufs);
	rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, 0, rx_bufs,
		     NULL);
	rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), 0, 0, rx_bufs);
	if (rc) {
		QETH_CARD_TEXT_(card, 2, "1err%d", rc);
		return rc;
@@ -3415,8 +3414,9 @@ static unsigned int qeth_rx_refill_queue(struct qeth_card *card,
			return 0;
		}

		rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0,
			     queue->next_buf_to_init, count, NULL);
		rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), 0,
						  queue->next_buf_to_init,
						  count);
		if (rc) {
			QETH_CARD_TEXT(card, 2, "qinberr");
		}
@@ -3588,7 +3588,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
	}

	QETH_TXQ_STAT_INC(queue, doorbell);
	rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_OUTPUT, queue->queue_no,
	rc = qdio_add_bufs_to_output_queue(CARD_DDEV(card), queue->queue_no,
					   index, count, aob);

	switch (rc) {
@@ -3739,8 +3739,8 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, unsigned int qdio_err,
		}
		qeth_scrub_qdio_buffer(buffer, QDIO_MAX_ELEMENTS_PER_BUFFER);
	}
	rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, queue,
		     cq->next_buf_to_init, count, NULL);
	rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), queue,
					  cq->next_buf_to_init, count);
	if (rc) {
		dev_warn(&card->gdev->dev,
			"QDIO reported an error, rc=%i\n", rc);
+9 −6
Original line number Diff line number Diff line
@@ -154,7 +154,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
	/*
	 * put SBALs back to response queue
	 */
	if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, idx, count, NULL))
	if (qdio_add_bufs_to_input_queue(cdev, 0, idx, count))
		zfcp_erp_adapter_reopen(qdio->adapter, 0, "qdires2");
}

@@ -326,8 +326,9 @@ int zfcp_qdio_send(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)

	atomic_sub(sbal_number, &qdio->req_q_free);

	retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0,
			 q_req->sbal_first, sbal_number, NULL);
	retval = qdio_add_bufs_to_output_queue(qdio->adapter->ccw_device, 0,
					       q_req->sbal_first, sbal_number,
					       NULL);

	if (unlikely(retval)) {
		/* Failed to submit the IO, roll back our modifications. */
@@ -395,7 +396,10 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio)
	if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
		return;

	/* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */
	/*
	 * Clear QDIOUP flag, thus qdio_add_bufs_to_output_queue() is not called
	 * during qdio_shutdown().
	 */
	spin_lock_irq(&qdio->req_q_lock);
	atomic_andnot(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
	spin_unlock_irq(&qdio->req_q_lock);
@@ -498,8 +502,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
		sbale->addr = 0;
	}

	if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q,
		    NULL))
	if (qdio_add_bufs_to_input_queue(cdev, 0, 0, QDIO_MAX_BUFFERS_PER_Q))
		goto failed_qdio;

	/* set index of first available SBALS / number of available SBALS */