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: Julian Wiedmann <jwi@linux.ibm.com> Reviewed-by: Benjamin Block <bblock@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
		
							parent
							
								
									143a3a735d
								
							
						
					
					
						commit
						3db1db93e3
					
				| @ -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 *); | ||||
|  | ||||
| @ -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 */ | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -308,7 +308,6 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id, | ||||
|  */ | ||||
| static int zfcp_qdio_allocate(struct zfcp_qdio *qdio) | ||||
| { | ||||
| 	struct qdio_initialize init_data; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	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) | ||||
| 	if (ret) | ||||
| 		goto free_req_q; | ||||
| 
 | ||||
| 	zfcp_qdio_setup_init_data(&init_data, qdio); | ||||
| 	init_waitqueue_head(&qdio->req_q_wq); | ||||
| 
 | ||||
| 	ret = qdio_allocate(&init_data); | ||||
| 	ret = qdio_allocate(qdio->adapter->ccw_device, 1, 1); | ||||
| 	if (ret) | ||||
| 		goto free_res_q; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user