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

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
...@@ -336,9 +336,6 @@ struct qdio_initialize { ...@@ -336,9 +336,6 @@ struct qdio_initialize {
struct qdio_buffer ***output_sbal_addr_array; 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); int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count);
void qdio_free_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); 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, ...@@ -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, extern int qdio_establish(struct ccw_device *cdev,
struct qdio_initialize *init_data); struct qdio_initialize *init_data);
extern int qdio_activate(struct ccw_device *); 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_start_irq(struct ccw_device *cdev);
extern int qdio_stop_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, extern int qdio_inspect_input_queue(struct ccw_device *cdev, unsigned int nr,
unsigned int *bufnr, unsigned int *error); unsigned int *bufnr, unsigned int *error);
extern int qdio_inspect_output_queue(struct ccw_device *cdev, unsigned int nr, extern int qdio_inspect_output_queue(struct ccw_device *cdev, unsigned int nr,
unsigned int *bufnr, unsigned int *error); 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_shutdown(struct ccw_device *, int);
extern int qdio_free(struct ccw_device *); extern int qdio_free(struct ccw_device *);
extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *); extern int qdio_get_ssqd_desc(struct ccw_device *, struct qdio_ssqd_desc *);
......
...@@ -1214,6 +1214,35 @@ static int handle_inbound(struct qdio_q *q, int bufnr, int count) ...@@ -1214,6 +1214,35 @@ static int handle_inbound(struct qdio_q *q, int bufnr, int count)
return 0; 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 * handle_outbound - process filled outbound buffers
* @q: queue containing the buffers * @q: queue containing the buffers
...@@ -1255,16 +1284,16 @@ static int handle_outbound(struct qdio_q *q, unsigned int bufnr, unsigned int co ...@@ -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 * @cdev: associated ccw_device for the qdio subchannel
* @callflags: input or output and special flags from the program
* @q_nr: queue number * @q_nr: queue number
* @bufnr: buffer number * @bufnr: buffer number
* @count: how many buffers to process * @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 qdio_add_bufs_to_output_queue(struct ccw_device *cdev, unsigned int q_nr,
int q_nr, unsigned int bufnr, unsigned int count, struct qaob *aob) unsigned int bufnr, unsigned int count,
struct qaob *aob)
{ {
struct qdio_irq *irq_ptr = cdev->private->qdio_data; struct qdio_irq *irq_ptr = cdev->private->qdio_data;
...@@ -1274,20 +1303,16 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags, ...@@ -1274,20 +1303,16 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
if (!irq_ptr) if (!irq_ptr)
return -ENODEV; return -ENODEV;
DBF_DEV_EVENT(DBF_INFO, irq_ptr, DBF_DEV_EVENT(DBF_INFO, irq_ptr, "addo b:%02x c:%02x", bufnr, count);
"do%02x b:%02x c:%02x", callflags, bufnr, count);
if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)
return -EIO; return -EIO;
if (!count) if (!count)
return 0; 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 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 * qdio_start_irq - enable interrupt processing for the device
......
...@@ -355,8 +355,8 @@ static int qeth_cq_init(struct qeth_card *card) ...@@ -355,8 +355,8 @@ static int qeth_cq_init(struct qeth_card *card)
qdio_reset_buffers(card->qdio.c_q->qdio_bufs, qdio_reset_buffers(card->qdio.c_q->qdio_bufs,
QDIO_MAX_BUFFERS_PER_Q); QDIO_MAX_BUFFERS_PER_Q);
card->qdio.c_q->next_buf_to_init = 127; 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) { if (rc) {
QETH_CARD_TEXT_(card, 2, "1err%d", rc); QETH_CARD_TEXT_(card, 2, "1err%d", rc);
goto out; goto out;
...@@ -2926,8 +2926,7 @@ static int qeth_init_qdio_queues(struct qeth_card *card) ...@@ -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); 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, rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), 0, 0, rx_bufs);
NULL);
if (rc) { if (rc) {
QETH_CARD_TEXT_(card, 2, "1err%d", rc); QETH_CARD_TEXT_(card, 2, "1err%d", rc);
return rc; return rc;
...@@ -3415,8 +3414,9 @@ static unsigned int qeth_rx_refill_queue(struct qeth_card *card, ...@@ -3415,8 +3414,9 @@ static unsigned int qeth_rx_refill_queue(struct qeth_card *card,
return 0; return 0;
} }
rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, 0, rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), 0,
queue->next_buf_to_init, count, NULL); queue->next_buf_to_init,
count);
if (rc) { if (rc) {
QETH_CARD_TEXT(card, 2, "qinberr"); QETH_CARD_TEXT(card, 2, "qinberr");
} }
...@@ -3588,7 +3588,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index, ...@@ -3588,7 +3588,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
} }
QETH_TXQ_STAT_INC(queue, doorbell); 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); index, count, aob);
switch (rc) { switch (rc) {
...@@ -3739,8 +3739,8 @@ static void qeth_qdio_cq_handler(struct qeth_card *card, unsigned int qdio_err, ...@@ -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); qeth_scrub_qdio_buffer(buffer, QDIO_MAX_ELEMENTS_PER_BUFFER);
} }
rc = do_QDIO(CARD_DDEV(card), QDIO_FLAG_SYNC_INPUT, queue, rc = qdio_add_bufs_to_input_queue(CARD_DDEV(card), queue,
cq->next_buf_to_init, count, NULL); cq->next_buf_to_init, count);
if (rc) { if (rc) {
dev_warn(&card->gdev->dev, dev_warn(&card->gdev->dev,
"QDIO reported an error, rc=%i\n", rc); "QDIO reported an error, rc=%i\n", rc);
......
...@@ -154,7 +154,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, ...@@ -154,7 +154,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err,
/* /*
* put SBALs back to response queue * 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"); 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) ...@@ -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); atomic_sub(sbal_number, &qdio->req_q_free);
retval = do_QDIO(qdio->adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, retval = qdio_add_bufs_to_output_queue(qdio->adapter->ccw_device, 0,
q_req->sbal_first, sbal_number, NULL); q_req->sbal_first, sbal_number,
NULL);
if (unlikely(retval)) { if (unlikely(retval)) {
/* Failed to submit the IO, roll back our modifications. */ /* Failed to submit the IO, roll back our modifications. */
...@@ -395,7 +396,10 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio) ...@@ -395,7 +396,10 @@ void zfcp_qdio_close(struct zfcp_qdio *qdio)
if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP)) if (!(atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_QDIOUP))
return; 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); spin_lock_irq(&qdio->req_q_lock);
atomic_andnot(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); atomic_andnot(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
spin_unlock_irq(&qdio->req_q_lock); spin_unlock_irq(&qdio->req_q_lock);
...@@ -498,8 +502,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio) ...@@ -498,8 +502,7 @@ int zfcp_qdio_open(struct zfcp_qdio *qdio)
sbale->addr = 0; sbale->addr = 0;
} }
if (do_QDIO(cdev, QDIO_FLAG_SYNC_INPUT, 0, 0, QDIO_MAX_BUFFERS_PER_Q, if (qdio_add_bufs_to_input_queue(cdev, 0, 0, QDIO_MAX_BUFFERS_PER_Q))
NULL))
goto failed_qdio; goto failed_qdio;
/* set index of first available SBALS / number of available SBALS */ /* set index of first available SBALS / number of available SBALS */
......
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