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

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
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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_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_activate(struct ccw_device *);
extern void qdio_release_aob(struct qaob *);
+1 −15
Original line number Diff line number Diff line
@@ -58,25 +58,11 @@ static void qdio_clear_dbf_list(void)
	mutex_unlock(&qdio_dbf_list_mutex);
}

int qdio_allocate_dbf(struct qdio_initialize *init_data,
		       struct qdio_irq *irq_ptr)
int qdio_allocate_dbf(struct qdio_irq *irq_ptr)
{
	char text[QDIO_DBF_NAME_LEN];
	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);

	/* allocate trace view for the interface */
+1 −2
Original line number Diff line number Diff line
@@ -64,8 +64,7 @@ static inline void DBF_DEV_HEX(struct qdio_irq *dev, void *addr,
	debug_event(dev->debug_area, level, addr, len);
}

int qdio_allocate_dbf(struct qdio_initialize *init_data,
		       struct qdio_irq *irq_ptr);
int qdio_allocate_dbf(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);
int qdio_debug_init(void);
+40 −16
Original line number Diff line number Diff line
@@ -1220,27 +1220,21 @@ EXPORT_SYMBOL_GPL(qdio_free);

/**
 * 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 qdio_irq *irq_ptr;

	ccw_device_get_schid(cdev, &schid);
	DBF_EVENT("qallocate:%4x", schid.sch_no);

	if ((init_data->no_input_qs && !init_data->input_handler) ||
	    (init_data->no_output_qs && !init_data->output_handler))
		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))
	if (no_input_qs > QDIO_MAX_QUEUES_PER_IRQ ||
	    no_output_qs > QDIO_MAX_QUEUES_PER_IRQ)
		return -EINVAL;

	/* irq_ptr must be in GFP_DMA since it contains ccw1.cda */
@@ -1250,9 +1244,12 @@ int qdio_allocate(struct qdio_initialize *init_data)

	irq_ptr->cdev = cdev;
	mutex_init(&irq_ptr->setup_mutex);
	if (qdio_allocate_dbf(init_data, irq_ptr))
	if (qdio_allocate_dbf(irq_ptr))
		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.
	 * Must be pre-allocated since a zfcp recovery will call
@@ -1268,8 +1265,7 @@ int qdio_allocate(struct qdio_initialize *init_data)
	if (!irq_ptr->qdr)
		goto out_rel;

	if (qdio_allocate_qs(irq_ptr, init_data->no_input_qs,
			     init_data->no_output_qs))
	if (qdio_allocate_qs(irq_ptr, no_input_qs, no_output_qs))
		goto out_rel;

	INIT_LIST_HEAD(&irq_ptr->entry);
@@ -1305,6 +1301,25 @@ static void qdio_detect_hsicq(struct qdio_irq *irq_ptr)
	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
 * @init_data: initialization data
@@ -1322,7 +1337,16 @@ int qdio_establish(struct qdio_initialize *init_data)
	if (!irq_ptr)
		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);
	qdio_trace_init_data(irq_ptr, init_data);
	qdio_setup_irq(irq_ptr, init_data);

	rc = qdio_establish_thinint(irq_ptr);
+2 −1
Original line number Diff line number Diff line
@@ -4893,7 +4893,8 @@ static int qeth_qdio_establish(struct qeth_card *card)

	if (atomic_cmpxchg(&card->qdio.state, 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) {
			atomic_set(&card->qdio.state, QETH_QDIO_ALLOCATED);
			goto out;
Loading