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: Julian Wiedmann <jwi@linux.ibm.com> Reviewed-by: Benjamin Block <bblock@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
parent
b44995e515
commit
a60bffe536
|
@ -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,
|
||||||
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)
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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,
|
||||||
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);
|
return handle_outbound(irq_ptr->output_qs[q_nr], bufnr, count, aob);
|
||||||
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
|
* qdio_start_irq - enable interrupt processing for the device
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,8 +3588,8 @@ 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) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -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,
|
||||||
/*
|
/*
|
||||||
* 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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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 */
|
||||||
|
|
Loading…
Reference in New Issue