Commit 3db1db93 authored by Julian Wiedmann's avatar Julian Wiedmann Committed by Vasily Gorbik

s390/qdio: cleanly split alloc and establish

All that qdio_allocate() actually uses from the init_data is the cdev,
and the number of Input and Output Queues. Have the driver pass those as
parameters, and defer the init_data processing into qdio_establish().
This includes writing per-device(!) trace entries, and most of the
sanity checks.
Signed-off-by: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: default avatarBenjamin Block <bblock@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 143a3a73
...@@ -408,7 +408,8 @@ int qdio_alloc_buffers(struct qdio_buffer **buf, unsigned int count); ...@@ -408,7 +408,8 @@ 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);
extern int qdio_allocate(struct qdio_initialize *); extern int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
unsigned int no_output_qs);
extern int qdio_establish(struct qdio_initialize *); extern int qdio_establish(struct qdio_initialize *);
extern int qdio_activate(struct ccw_device *); extern int qdio_activate(struct ccw_device *);
extern void qdio_release_aob(struct qaob *); extern void qdio_release_aob(struct qaob *);
......
...@@ -58,25 +58,11 @@ static void qdio_clear_dbf_list(void) ...@@ -58,25 +58,11 @@ static void qdio_clear_dbf_list(void)
mutex_unlock(&qdio_dbf_list_mutex); mutex_unlock(&qdio_dbf_list_mutex);
} }
int qdio_allocate_dbf(struct qdio_initialize *init_data, int qdio_allocate_dbf(struct qdio_irq *irq_ptr)
struct qdio_irq *irq_ptr)
{ {
char text[QDIO_DBF_NAME_LEN]; char text[QDIO_DBF_NAME_LEN];
struct qdio_dbf_entry *new_entry; struct qdio_dbf_entry *new_entry;
DBF_EVENT("qfmt:%1d", init_data->q_format);
DBF_HEX(init_data->adapter_name, 8);
DBF_EVENT("qpff%4x", init_data->qib_param_field_format);
DBF_HEX(&init_data->qib_param_field, sizeof(void *));
DBF_HEX(&init_data->input_slib_elements, sizeof(void *));
DBF_HEX(&init_data->output_slib_elements, sizeof(void *));
DBF_EVENT("niq:%1d noq:%1d", init_data->no_input_qs,
init_data->no_output_qs);
DBF_HEX(&init_data->input_handler, sizeof(void *));
DBF_HEX(&init_data->output_handler, sizeof(void *));
DBF_HEX(&init_data->int_parm, sizeof(long));
DBF_HEX(&init_data->input_sbal_addr_array, sizeof(void *));
DBF_HEX(&init_data->output_sbal_addr_array, sizeof(void *));
DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr); DBF_EVENT("irq:%8lx", (unsigned long)irq_ptr);
/* allocate trace view for the interface */ /* allocate trace view for the interface */
......
...@@ -64,8 +64,7 @@ static inline void DBF_DEV_HEX(struct qdio_irq *dev, void *addr, ...@@ -64,8 +64,7 @@ static inline void DBF_DEV_HEX(struct qdio_irq *dev, void *addr,
debug_event(dev->debug_area, level, addr, len); debug_event(dev->debug_area, level, addr, len);
} }
int qdio_allocate_dbf(struct qdio_initialize *init_data, int qdio_allocate_dbf(struct qdio_irq *irq_ptr);
struct qdio_irq *irq_ptr);
void qdio_setup_debug_entries(struct qdio_irq *irq_ptr); void qdio_setup_debug_entries(struct qdio_irq *irq_ptr);
void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr); void qdio_shutdown_debug_entries(struct qdio_irq *irq_ptr);
int qdio_debug_init(void); int qdio_debug_init(void);
......
...@@ -1220,27 +1220,21 @@ EXPORT_SYMBOL_GPL(qdio_free); ...@@ -1220,27 +1220,21 @@ EXPORT_SYMBOL_GPL(qdio_free);
/** /**
* qdio_allocate - allocate qdio queues and associated data * qdio_allocate - allocate qdio queues and associated data
* @init_data: initialization data * @cdev: associated ccw device
* @no_input_qs: allocate this number of Input Queues
* @no_output_qs: allocate this number of Output Queues
*/ */
int qdio_allocate(struct qdio_initialize *init_data) int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
unsigned int no_output_qs)
{ {
struct ccw_device *cdev = init_data->cdev;
struct subchannel_id schid; struct subchannel_id schid;
struct qdio_irq *irq_ptr; struct qdio_irq *irq_ptr;
ccw_device_get_schid(cdev, &schid); ccw_device_get_schid(cdev, &schid);
DBF_EVENT("qallocate:%4x", schid.sch_no); DBF_EVENT("qallocate:%4x", schid.sch_no);
if ((init_data->no_input_qs && !init_data->input_handler) || if (no_input_qs > QDIO_MAX_QUEUES_PER_IRQ ||
(init_data->no_output_qs && !init_data->output_handler)) no_output_qs > QDIO_MAX_QUEUES_PER_IRQ)
return -EINVAL;
if ((init_data->no_input_qs > QDIO_MAX_QUEUES_PER_IRQ) ||
(init_data->no_output_qs > QDIO_MAX_QUEUES_PER_IRQ))
return -EINVAL;
if ((!init_data->input_sbal_addr_array) ||
(!init_data->output_sbal_addr_array))
return -EINVAL; return -EINVAL;
/* irq_ptr must be in GFP_DMA since it contains ccw1.cda */ /* irq_ptr must be in GFP_DMA since it contains ccw1.cda */
...@@ -1250,9 +1244,12 @@ int qdio_allocate(struct qdio_initialize *init_data) ...@@ -1250,9 +1244,12 @@ int qdio_allocate(struct qdio_initialize *init_data)
irq_ptr->cdev = cdev; irq_ptr->cdev = cdev;
mutex_init(&irq_ptr->setup_mutex); mutex_init(&irq_ptr->setup_mutex);
if (qdio_allocate_dbf(init_data, irq_ptr)) if (qdio_allocate_dbf(irq_ptr))
goto out_rel; goto out_rel;
DBF_DEV_EVENT(DBF_ERR, irq_ptr, "alloc niq:%1u noq:%1u", no_input_qs,
no_output_qs);
/* /*
* Allocate a page for the chsc calls in qdio_establish. * Allocate a page for the chsc calls in qdio_establish.
* Must be pre-allocated since a zfcp recovery will call * Must be pre-allocated since a zfcp recovery will call
...@@ -1268,8 +1265,7 @@ int qdio_allocate(struct qdio_initialize *init_data) ...@@ -1268,8 +1265,7 @@ int qdio_allocate(struct qdio_initialize *init_data)
if (!irq_ptr->qdr) if (!irq_ptr->qdr)
goto out_rel; goto out_rel;
if (qdio_allocate_qs(irq_ptr, init_data->no_input_qs, if (qdio_allocate_qs(irq_ptr, no_input_qs, no_output_qs))
init_data->no_output_qs))
goto out_rel; goto out_rel;
INIT_LIST_HEAD(&irq_ptr->entry); INIT_LIST_HEAD(&irq_ptr->entry);
...@@ -1305,6 +1301,25 @@ static void qdio_detect_hsicq(struct qdio_irq *irq_ptr) ...@@ -1305,6 +1301,25 @@ static void qdio_detect_hsicq(struct qdio_irq *irq_ptr)
DBF_EVENT("use_cq:%d", use_cq); DBF_EVENT("use_cq:%d", use_cq);
} }
static void qdio_trace_init_data(struct qdio_irq *irq,
struct qdio_initialize *data)
{
DBF_DEV_EVENT(DBF_ERR, irq, "qfmt:%1u", data->q_format);
DBF_DEV_HEX(irq, data->adapter_name, 8, DBF_ERR);
DBF_DEV_EVENT(DBF_ERR, irq, "qpff%4x", data->qib_param_field_format);
DBF_DEV_HEX(irq, &data->qib_param_field, sizeof(void *), DBF_ERR);
DBF_DEV_HEX(irq, &data->input_slib_elements, sizeof(void *), DBF_ERR);
DBF_DEV_HEX(irq, &data->output_slib_elements, sizeof(void *), DBF_ERR);
DBF_DEV_EVENT(DBF_ERR, irq, "niq:%1u noq:%1u", data->no_input_qs,
data->no_output_qs);
DBF_DEV_HEX(irq, &data->input_handler, sizeof(void *), DBF_ERR);
DBF_DEV_HEX(irq, &data->output_handler, sizeof(void *), DBF_ERR);
DBF_DEV_HEX(irq, &data->int_parm, sizeof(long), DBF_ERR);
DBF_DEV_HEX(irq, &data->input_sbal_addr_array, sizeof(void *), DBF_ERR);
DBF_DEV_HEX(irq, &data->output_sbal_addr_array, sizeof(void *),
DBF_ERR);
}
/** /**
* qdio_establish - establish queues on a qdio subchannel * qdio_establish - establish queues on a qdio subchannel
* @init_data: initialization data * @init_data: initialization data
...@@ -1322,7 +1337,16 @@ int qdio_establish(struct qdio_initialize *init_data) ...@@ -1322,7 +1337,16 @@ int qdio_establish(struct qdio_initialize *init_data)
if (!irq_ptr) if (!irq_ptr)
return -ENODEV; return -ENODEV;
if ((init_data->no_input_qs && !init_data->input_handler) ||
(init_data->no_output_qs && !init_data->output_handler))
return -EINVAL;
if (!init_data->input_sbal_addr_array ||
!init_data->output_sbal_addr_array)
return -EINVAL;
mutex_lock(&irq_ptr->setup_mutex); mutex_lock(&irq_ptr->setup_mutex);
qdio_trace_init_data(irq_ptr, init_data);
qdio_setup_irq(irq_ptr, init_data); qdio_setup_irq(irq_ptr, init_data);
rc = qdio_establish_thinint(irq_ptr); rc = qdio_establish_thinint(irq_ptr);
......
...@@ -4893,7 +4893,8 @@ static int qeth_qdio_establish(struct qeth_card *card) ...@@ -4893,7 +4893,8 @@ static int qeth_qdio_establish(struct qeth_card *card)
if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED, if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) { QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) {
rc = qdio_allocate(&init_data); rc = qdio_allocate(CARD_DDEV(card), init_data.no_input_qs,
init_data.no_output_qs);
if (rc) { if (rc) {
atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED); atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
goto out; goto out;
......
...@@ -308,7 +308,6 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, ...@@ -308,7 +308,6 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
*/ */
static int zfcp_qdio_allocate(struct zfcp_qdio *qdio) static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
{ {
struct qdio_initialize init_data;
int ret; int ret;
ret = qdio_alloc_buffers(qdio->req_q, QDIO_MAX_BUFFERS_PER_Q); ret = qdio_alloc_buffers(qdio->req_q, QDIO_MAX_BUFFERS_PER_Q);
...@@ -319,10 +318,9 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio) ...@@ -319,10 +318,9 @@ static int zfcp_qdio_allocate(struct zfcp_qdio *qdio)
if (ret) if (ret)
goto free_req_q; goto free_req_q;
zfcp_qdio_setup_init_data(&init_data, qdio);
init_waitqueue_head(&qdio->req_q_wq); init_waitqueue_head(&qdio->req_q_wq);
ret = qdio_allocate(&init_data); ret = qdio_allocate(qdio->adapter->ccw_device, 1, 1);
if (ret) if (ret)
goto free_res_q; goto free_res_q;
......
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