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:
Родитель
b44995e515
Коммит
a60bffe536
|
@ -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 *);
|
||||
|
|
|
@ -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;
|
||||
|
||||
return handle_outbound(irq_ptr->output_qs[q_nr], bufnr, count, aob);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(do_QDIO);
|
||||
EXPORT_SYMBOL_GPL(qdio_add_bufs_to_output_queue);
|
||||
|
||||
/**
|
||||
* 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_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,8 +3588,8 @@ 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,
|
||||
index, count, aob);
|
||||
rc = qdio_add_bufs_to_output_queue(CARD_DDEV(card), queue->queue_no,
|
||||
index, count, aob);
|
||||
|
||||
switch (rc) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче