[SCSI] qla2xxx: Refactor shutdown code so some functionality can be reused.
Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
		
					parent
					
						
							
								50280c014d
							
						
					
				
			
			
				commit
				
					
						fe1b806f4f
					
				
			
		
					 3 changed files with 96 additions and 81 deletions
				
			
		|  | @ -862,7 +862,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void | void | ||||||
| qla2x00_free_sysfs_attr(scsi_qla_host_t *vha) | qla2x00_free_sysfs_attr(scsi_qla_host_t *vha, bool stop_beacon) | ||||||
| { | { | ||||||
| 	struct Scsi_Host *host = vha->host; | 	struct Scsi_Host *host = vha->host; | ||||||
| 	struct sysfs_entry *iter; | 	struct sysfs_entry *iter; | ||||||
|  | @ -880,7 +880,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha) | ||||||
| 		    iter->attr); | 		    iter->attr); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (ha->beacon_blink_led == 1) | 	if (stop_beacon && ha->beacon_blink_led == 1) | ||||||
| 		ha->isp_ops->beacon_off(vha); | 		ha->isp_ops->beacon_off(vha); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -540,10 +540,9 @@ struct fc_function_template; | ||||||
| extern struct fc_function_template qla2xxx_transport_functions; | extern struct fc_function_template qla2xxx_transport_functions; | ||||||
| extern struct fc_function_template qla2xxx_transport_vport_functions; | extern struct fc_function_template qla2xxx_transport_vport_functions; | ||||||
| extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); | extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); | ||||||
| extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); | extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *, bool); | ||||||
| extern void qla2x00_init_host_attr(scsi_qla_host_t *); | extern void qla2x00_init_host_attr(scsi_qla_host_t *); | ||||||
| extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); | extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); | ||||||
| extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); |  | ||||||
| extern int qla2x00_loopback_test(scsi_qla_host_t *, struct msg_echo_lb *, uint16_t *); | extern int qla2x00_loopback_test(scsi_qla_host_t *, struct msg_echo_lb *, uint16_t *); | ||||||
| extern int qla2x00_echo_test(scsi_qla_host_t *, | extern int qla2x00_echo_test(scsi_qla_host_t *, | ||||||
| 	struct msg_echo_lb *, uint16_t *); | 	struct msg_echo_lb *, uint16_t *); | ||||||
|  |  | ||||||
|  | @ -2905,22 +2905,6 @@ probe_out: | ||||||
| 	return ret; | 	return ret; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void |  | ||||||
| qla2x00_stop_dpc_thread(scsi_qla_host_t *vha) |  | ||||||
| { |  | ||||||
| 	struct qla_hw_data *ha = vha->hw; |  | ||||||
| 	struct task_struct *t = ha->dpc_thread; |  | ||||||
| 
 |  | ||||||
| 	if (ha->dpc_thread == NULL) |  | ||||||
| 		return; |  | ||||||
| 	/*
 |  | ||||||
| 	 * qla2xxx_wake_dpc checks for ->dpc_thread |  | ||||||
| 	 * so we need to zero it out. |  | ||||||
| 	 */ |  | ||||||
| 	ha->dpc_thread = NULL; |  | ||||||
| 	kthread_stop(t); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void | static void | ||||||
| qla2x00_shutdown(struct pci_dev *pdev) | qla2x00_shutdown(struct pci_dev *pdev) | ||||||
| { | { | ||||||
|  | @ -2964,29 +2948,14 @@ qla2x00_shutdown(struct pci_dev *pdev) | ||||||
| 	qla2x00_free_fw_dump(ha); | 	qla2x00_free_fw_dump(ha); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /* Deletes all the virtual ports for a given ha */ | ||||||
| static void | static void | ||||||
| qla2x00_remove_one(struct pci_dev *pdev) | qla2x00_delete_all_vps(struct qla_hw_data *ha, scsi_qla_host_t *base_vha) | ||||||
| { | { | ||||||
| 	scsi_qla_host_t *base_vha, *vha; | 	struct Scsi_Host *scsi_host; | ||||||
| 	struct qla_hw_data  *ha; | 	scsi_qla_host_t *vha; | ||||||
| 	unsigned long flags; | 	unsigned long flags; | ||||||
| 
 | 
 | ||||||
| 	/*
 |  | ||||||
| 	 * If the PCI device is disabled that means that probe failed and any |  | ||||||
| 	 * resources should be have cleaned up on probe exit. |  | ||||||
| 	 */ |  | ||||||
| 	if (!atomic_read(&pdev->enable_cnt)) |  | ||||||
| 		return; |  | ||||||
| 
 |  | ||||||
| 	base_vha = pci_get_drvdata(pdev); |  | ||||||
| 	ha = base_vha->hw; |  | ||||||
| 
 |  | ||||||
| 	ha->flags.host_shutting_down = 1; |  | ||||||
| 
 |  | ||||||
| 	set_bit(UNLOADING, &base_vha->dpc_flags); |  | ||||||
| 	if (IS_QLAFX00(ha)) |  | ||||||
| 		qlafx00_driver_shutdown(base_vha, 20); |  | ||||||
| 
 |  | ||||||
| 	mutex_lock(&ha->vport_lock); | 	mutex_lock(&ha->vport_lock); | ||||||
| 	while (ha->cur_vport_count) { | 	while (ha->cur_vport_count) { | ||||||
| 		spin_lock_irqsave(&ha->vport_slock, flags); | 		spin_lock_irqsave(&ha->vport_slock, flags); | ||||||
|  | @ -2994,7 +2963,7 @@ qla2x00_remove_one(struct pci_dev *pdev) | ||||||
| 		BUG_ON(base_vha->list.next == &ha->vp_list); | 		BUG_ON(base_vha->list.next == &ha->vp_list); | ||||||
| 		/* This assumes first entry in ha->vp_list is always base vha */ | 		/* This assumes first entry in ha->vp_list is always base vha */ | ||||||
| 		vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list); | 		vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list); | ||||||
| 		scsi_host_get(vha->host); | 		scsi_host = scsi_host_get(vha->host); | ||||||
| 
 | 
 | ||||||
| 		spin_unlock_irqrestore(&ha->vport_slock, flags); | 		spin_unlock_irqrestore(&ha->vport_slock, flags); | ||||||
| 		mutex_unlock(&ha->vport_lock); | 		mutex_unlock(&ha->vport_lock); | ||||||
|  | @ -3005,27 +2974,12 @@ qla2x00_remove_one(struct pci_dev *pdev) | ||||||
| 		mutex_lock(&ha->vport_lock); | 		mutex_lock(&ha->vport_lock); | ||||||
| 	} | 	} | ||||||
| 	mutex_unlock(&ha->vport_lock); | 	mutex_unlock(&ha->vport_lock); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 	if (IS_QLA8031(ha)) { | /* Stops all deferred work threads */ | ||||||
| 		ql_dbg(ql_dbg_p3p, base_vha, 0xb07e, | static void | ||||||
| 		    "Clearing fcoe driver presence.\n"); | qla2x00_destroy_deferred_work(struct qla_hw_data *ha) | ||||||
| 		if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS) | { | ||||||
| 			ql_dbg(ql_dbg_p3p, base_vha, 0xb079, |  | ||||||
| 			    "Error while clearing DRV-Presence.\n"); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); |  | ||||||
| 
 |  | ||||||
| 	qla2x00_dfs_remove(base_vha); |  | ||||||
| 
 |  | ||||||
| 	qla84xx_put_chip(base_vha); |  | ||||||
| 
 |  | ||||||
| 	/* Disable timer */ |  | ||||||
| 	if (base_vha->timer_active) |  | ||||||
| 		qla2x00_stop_timer(base_vha); |  | ||||||
| 
 |  | ||||||
| 	base_vha->flags.online = 0; |  | ||||||
| 
 |  | ||||||
| 	/* Flush the work queue and remove it */ | 	/* Flush the work queue and remove it */ | ||||||
| 	if (ha->wq) { | 	if (ha->wq) { | ||||||
| 		flush_workqueue(ha->wq); | 		flush_workqueue(ha->wq); | ||||||
|  | @ -3059,27 +3013,12 @@ qla2x00_remove_one(struct pci_dev *pdev) | ||||||
| 		ha->dpc_thread = NULL; | 		ha->dpc_thread = NULL; | ||||||
| 		kthread_stop(t); | 		kthread_stop(t); | ||||||
| 	} | 	} | ||||||
| 	qlt_remove_target(ha, base_vha); | } | ||||||
| 
 | 
 | ||||||
| 	qla2x00_free_sysfs_attr(base_vha); | static void | ||||||
| 
 | qla2x00_unmap_iobases(struct qla_hw_data *ha) | ||||||
| 	fc_remove_host(base_vha->host); | { | ||||||
| 
 |  | ||||||
| 	scsi_remove_host(base_vha->host); |  | ||||||
| 
 |  | ||||||
| 	qla2x00_free_device(base_vha); |  | ||||||
| 
 |  | ||||||
| 	scsi_host_put(base_vha->host); |  | ||||||
| 
 |  | ||||||
| 	if (IS_QLA8044(ha)) { |  | ||||||
| 		qla8044_idc_lock(ha); |  | ||||||
| 		qla8044_clear_drv_active(base_vha); |  | ||||||
| 		qla8044_idc_unlock(ha); |  | ||||||
| 	} |  | ||||||
| 	if (IS_QLA82XX(ha)) { | 	if (IS_QLA82XX(ha)) { | ||||||
| 		qla82xx_idc_lock(ha); |  | ||||||
| 		qla82xx_clear_drv_active(ha); |  | ||||||
| 		qla82xx_idc_unlock(ha); |  | ||||||
| 
 | 
 | ||||||
| 		iounmap((device_reg_t __iomem *)ha->nx_pcibase); | 		iounmap((device_reg_t __iomem *)ha->nx_pcibase); | ||||||
| 		if (!ql2xdbwr) | 		if (!ql2xdbwr) | ||||||
|  | @ -3097,6 +3036,84 @@ qla2x00_remove_one(struct pci_dev *pdev) | ||||||
| 		if (IS_QLA83XX(ha) && ha->msixbase) | 		if (IS_QLA83XX(ha) && ha->msixbase) | ||||||
| 			iounmap(ha->msixbase); | 			iounmap(ha->msixbase); | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | qla2x00_clear_drv_active(scsi_qla_host_t *vha) | ||||||
|  | { | ||||||
|  | 	struct qla_hw_data *ha = vha->hw; | ||||||
|  | 
 | ||||||
|  | 	if (IS_QLA8044(ha)) { | ||||||
|  | 		qla8044_idc_lock(ha); | ||||||
|  | 		qla8044_clear_drv_active(vha); | ||||||
|  | 		qla8044_idc_unlock(ha); | ||||||
|  | 	} else if (IS_QLA82XX(ha)) { | ||||||
|  | 		qla82xx_idc_lock(ha); | ||||||
|  | 		qla82xx_clear_drv_active(ha); | ||||||
|  | 		qla82xx_idc_unlock(ha); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | qla2x00_remove_one(struct pci_dev *pdev) | ||||||
|  | { | ||||||
|  | 	scsi_qla_host_t *base_vha; | ||||||
|  | 	struct qla_hw_data  *ha; | ||||||
|  | 
 | ||||||
|  | 	/*
 | ||||||
|  | 	 * If the PCI device is disabled that means that probe failed and any | ||||||
|  | 	 * resources should be have cleaned up on probe exit. | ||||||
|  | 	 */ | ||||||
|  | 	if (!atomic_read(&pdev->enable_cnt)) | ||||||
|  | 		return; | ||||||
|  | 
 | ||||||
|  | 	base_vha = pci_get_drvdata(pdev); | ||||||
|  | 	ha = base_vha->hw; | ||||||
|  | 
 | ||||||
|  | 	set_bit(UNLOADING, &base_vha->dpc_flags); | ||||||
|  | 
 | ||||||
|  | 	if (IS_QLAFX00(ha)) | ||||||
|  | 		qlafx00_driver_shutdown(base_vha, 20); | ||||||
|  | 
 | ||||||
|  | 	qla2x00_delete_all_vps(ha, base_vha); | ||||||
|  | 
 | ||||||
|  | 	if (IS_QLA8031(ha)) { | ||||||
|  | 		ql_dbg(ql_dbg_p3p, base_vha, 0xb07e, | ||||||
|  | 		    "Clearing fcoe driver presence.\n"); | ||||||
|  | 		if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS) | ||||||
|  | 			ql_dbg(ql_dbg_p3p, base_vha, 0xb079, | ||||||
|  | 			    "Error while clearing DRV-Presence.\n"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16); | ||||||
|  | 
 | ||||||
|  | 	qla2x00_dfs_remove(base_vha); | ||||||
|  | 
 | ||||||
|  | 	qla84xx_put_chip(base_vha); | ||||||
|  | 
 | ||||||
|  | 	/* Disable timer */ | ||||||
|  | 	if (base_vha->timer_active) | ||||||
|  | 		qla2x00_stop_timer(base_vha); | ||||||
|  | 
 | ||||||
|  | 	base_vha->flags.online = 0; | ||||||
|  | 
 | ||||||
|  | 	qla2x00_destroy_deferred_work(ha); | ||||||
|  | 
 | ||||||
|  | 	qlt_remove_target(ha, base_vha); | ||||||
|  | 
 | ||||||
|  | 	qla2x00_free_sysfs_attr(base_vha, true); | ||||||
|  | 
 | ||||||
|  | 	fc_remove_host(base_vha->host); | ||||||
|  | 
 | ||||||
|  | 	scsi_remove_host(base_vha->host); | ||||||
|  | 
 | ||||||
|  | 	qla2x00_free_device(base_vha); | ||||||
|  | 
 | ||||||
|  | 	scsi_host_put(base_vha->host); | ||||||
|  | 
 | ||||||
|  | 	qla2x00_clear_drv_active(base_vha); | ||||||
|  | 
 | ||||||
|  | 	qla2x00_unmap_iobases(ha); | ||||||
| 
 | 
 | ||||||
| 	pci_release_selected_regions(ha->pdev, ha->bars); | 	pci_release_selected_regions(ha->pdev, ha->bars); | ||||||
| 	kfree(ha); | 	kfree(ha); | ||||||
|  | @ -3118,9 +3135,8 @@ qla2x00_free_device(scsi_qla_host_t *vha) | ||||||
| 	if (vha->timer_active) | 	if (vha->timer_active) | ||||||
| 		qla2x00_stop_timer(vha); | 		qla2x00_stop_timer(vha); | ||||||
| 
 | 
 | ||||||
| 	qla2x00_stop_dpc_thread(vha); |  | ||||||
| 
 |  | ||||||
| 	qla25xx_delete_queues(vha); | 	qla25xx_delete_queues(vha); | ||||||
|  | 
 | ||||||
| 	if (ha->flags.fce_enabled) | 	if (ha->flags.fce_enabled) | ||||||
| 		qla2x00_disable_fce_trace(vha, NULL, NULL); | 		qla2x00_disable_fce_trace(vha, NULL, NULL); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Chad Dupuis
				Chad Dupuis