aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChad Dupuis <chad.dupuis@qlogic.com>2013-10-30 03:38:15 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-12-19 10:38:58 -0500
commitfe1b806f4f7172b1eae18ddeebb7d8fb351043f7 (patch)
treea18bba2af3f15f73dd953575af1054b529a4d20b
parent50280c014de9d10f430bfbf3b343784d4cf1fc15 (diff)
[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>
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h3
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c170
3 files changed, 96 insertions, 81 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index 5f174b83f56f..3464782ab5a4 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -862,7 +862,7 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
862} 862}
863 863
864void 864void
865qla2x00_free_sysfs_attr(scsi_qla_host_t *vha) 865qla2x00_free_sysfs_attr(scsi_qla_host_t *vha, bool stop_beacon)
866{ 866{
867 struct Scsi_Host *host = vha->host; 867 struct Scsi_Host *host = vha->host;
868 struct sysfs_entry *iter; 868 struct sysfs_entry *iter;
@@ -880,7 +880,7 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
880 iter->attr); 880 iter->attr);
881 } 881 }
882 882
883 if (ha->beacon_blink_led == 1) 883 if (stop_beacon && ha->beacon_blink_led == 1)
884 ha->isp_ops->beacon_off(vha); 884 ha->isp_ops->beacon_off(vha);
885} 885}
886 886
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 826df52131a5..df52f73acabd 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -540,10 +540,9 @@ struct fc_function_template;
540extern struct fc_function_template qla2xxx_transport_functions; 540extern struct fc_function_template qla2xxx_transport_functions;
541extern struct fc_function_template qla2xxx_transport_vport_functions; 541extern struct fc_function_template qla2xxx_transport_vport_functions;
542extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); 542extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
543extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); 543extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *, bool);
544extern void qla2x00_init_host_attr(scsi_qla_host_t *); 544extern void qla2x00_init_host_attr(scsi_qla_host_t *);
545extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); 545extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *);
546extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *);
547extern int qla2x00_loopback_test(scsi_qla_host_t *, struct msg_echo_lb *, uint16_t *); 546extern int qla2x00_loopback_test(scsi_qla_host_t *, struct msg_echo_lb *, uint16_t *);
548extern int qla2x00_echo_test(scsi_qla_host_t *, 547extern int qla2x00_echo_test(scsi_qla_host_t *,
549 struct msg_echo_lb *, uint16_t *); 548 struct msg_echo_lb *, uint16_t *);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index a725efa47b35..c9e4372698a2 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -2906,22 +2906,6 @@ probe_out:
2906} 2906}
2907 2907
2908static void 2908static void
2909qla2x00_stop_dpc_thread(scsi_qla_host_t *vha)
2910{
2911 struct qla_hw_data *ha = vha->hw;
2912 struct task_struct *t = ha->dpc_thread;
2913
2914 if (ha->dpc_thread == NULL)
2915 return;
2916 /*
2917 * qla2xxx_wake_dpc checks for ->dpc_thread
2918 * so we need to zero it out.
2919 */
2920 ha->dpc_thread = NULL;
2921 kthread_stop(t);
2922}
2923
2924static void
2925qla2x00_shutdown(struct pci_dev *pdev) 2909qla2x00_shutdown(struct pci_dev *pdev)
2926{ 2910{
2927 scsi_qla_host_t *vha; 2911 scsi_qla_host_t *vha;
@@ -2964,29 +2948,14 @@ qla2x00_shutdown(struct pci_dev *pdev)
2964 qla2x00_free_fw_dump(ha); 2948 qla2x00_free_fw_dump(ha);
2965} 2949}
2966 2950
2951/* Deletes all the virtual ports for a given ha */
2967static void 2952static void
2968qla2x00_remove_one(struct pci_dev *pdev) 2953qla2x00_delete_all_vps(struct qla_hw_data *ha, scsi_qla_host_t *base_vha)
2969{ 2954{
2970 scsi_qla_host_t *base_vha, *vha; 2955 struct Scsi_Host *scsi_host;
2971 struct qla_hw_data *ha; 2956 scsi_qla_host_t *vha;
2972 unsigned long flags; 2957 unsigned long flags;
2973 2958
2974 /*
2975 * If the PCI device is disabled that means that probe failed and any
2976 * resources should be have cleaned up on probe exit.
2977 */
2978 if (!atomic_read(&pdev->enable_cnt))
2979 return;
2980
2981 base_vha = pci_get_drvdata(pdev);
2982 ha = base_vha->hw;
2983
2984 ha->flags.host_shutting_down = 1;
2985
2986 set_bit(UNLOADING, &base_vha->dpc_flags);
2987 if (IS_QLAFX00(ha))
2988 qlafx00_driver_shutdown(base_vha, 20);
2989
2990 mutex_lock(&ha->vport_lock); 2959 mutex_lock(&ha->vport_lock);
2991 while (ha->cur_vport_count) { 2960 while (ha->cur_vport_count) {
2992 spin_lock_irqsave(&ha->vport_slock, flags); 2961 spin_lock_irqsave(&ha->vport_slock, flags);
@@ -2994,7 +2963,7 @@ qla2x00_remove_one(struct pci_dev *pdev)
2994 BUG_ON(base_vha->list.next == &ha->vp_list); 2963 BUG_ON(base_vha->list.next == &ha->vp_list);
2995 /* This assumes first entry in ha->vp_list is always base vha */ 2964 /* This assumes first entry in ha->vp_list is always base vha */
2996 vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list); 2965 vha = list_first_entry(&base_vha->list, scsi_qla_host_t, list);
2997 scsi_host_get(vha->host); 2966 scsi_host = scsi_host_get(vha->host);
2998 2967
2999 spin_unlock_irqrestore(&ha->vport_slock, flags); 2968 spin_unlock_irqrestore(&ha->vport_slock, flags);
3000 mutex_unlock(&ha->vport_lock); 2969 mutex_unlock(&ha->vport_lock);
@@ -3005,27 +2974,12 @@ qla2x00_remove_one(struct pci_dev *pdev)
3005 mutex_lock(&ha->vport_lock); 2974 mutex_lock(&ha->vport_lock);
3006 } 2975 }
3007 mutex_unlock(&ha->vport_lock); 2976 mutex_unlock(&ha->vport_lock);
2977}
3008 2978
3009 if (IS_QLA8031(ha)) { 2979/* Stops all deferred work threads */
3010 ql_dbg(ql_dbg_p3p, base_vha, 0xb07e, 2980static void
3011 "Clearing fcoe driver presence.\n"); 2981qla2x00_destroy_deferred_work(struct qla_hw_data *ha)
3012 if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS) 2982{
3013 ql_dbg(ql_dbg_p3p, base_vha, 0xb079,
3014 "Error while clearing DRV-Presence.\n");
3015 }
3016
3017 qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
3018
3019 qla2x00_dfs_remove(base_vha);
3020
3021 qla84xx_put_chip(base_vha);
3022
3023 /* Disable timer */
3024 if (base_vha->timer_active)
3025 qla2x00_stop_timer(base_vha);
3026
3027 base_vha->flags.online = 0;
3028
3029 /* Flush the work queue and remove it */ 2983 /* Flush the work queue and remove it */
3030 if (ha->wq) { 2984 if (ha->wq) {
3031 flush_workqueue(ha->wq); 2985 flush_workqueue(ha->wq);
@@ -3059,27 +3013,12 @@ qla2x00_remove_one(struct pci_dev *pdev)
3059 ha->dpc_thread = NULL; 3013 ha->dpc_thread = NULL;
3060 kthread_stop(t); 3014 kthread_stop(t);
3061 } 3015 }
3062 qlt_remove_target(ha, base_vha); 3016}
3063
3064 qla2x00_free_sysfs_attr(base_vha);
3065
3066 fc_remove_host(base_vha->host);
3067
3068 scsi_remove_host(base_vha->host);
3069
3070 qla2x00_free_device(base_vha);
3071
3072 scsi_host_put(base_vha->host);
3073 3017
3074 if (IS_QLA8044(ha)) { 3018static void
3075 qla8044_idc_lock(ha); 3019qla2x00_unmap_iobases(struct qla_hw_data *ha)
3076 qla8044_clear_drv_active(base_vha); 3020{
3077 qla8044_idc_unlock(ha);
3078 }
3079 if (IS_QLA82XX(ha)) { 3021 if (IS_QLA82XX(ha)) {
3080 qla82xx_idc_lock(ha);
3081 qla82xx_clear_drv_active(ha);
3082 qla82xx_idc_unlock(ha);
3083 3022
3084 iounmap((device_reg_t __iomem *)ha->nx_pcibase); 3023 iounmap((device_reg_t __iomem *)ha->nx_pcibase);
3085 if (!ql2xdbwr) 3024 if (!ql2xdbwr)
@@ -3097,6 +3036,84 @@ qla2x00_remove_one(struct pci_dev *pdev)
3097 if (IS_QLA83XX(ha) && ha->msixbase) 3036 if (IS_QLA83XX(ha) && ha->msixbase)
3098 iounmap(ha->msixbase); 3037 iounmap(ha->msixbase);
3099 } 3038 }
3039}
3040
3041static void
3042qla2x00_clear_drv_active(scsi_qla_host_t *vha)
3043{
3044 struct qla_hw_data *ha = vha->hw;
3045
3046 if (IS_QLA8044(ha)) {
3047 qla8044_idc_lock(ha);
3048 qla8044_clear_drv_active(vha);
3049 qla8044_idc_unlock(ha);
3050 } else if (IS_QLA82XX(ha)) {
3051 qla82xx_idc_lock(ha);
3052 qla82xx_clear_drv_active(ha);
3053 qla82xx_idc_unlock(ha);
3054 }
3055}
3056
3057static void
3058qla2x00_remove_one(struct pci_dev *pdev)
3059{
3060 scsi_qla_host_t *base_vha;
3061 struct qla_hw_data *ha;
3062
3063 /*
3064 * If the PCI device is disabled that means that probe failed and any
3065 * resources should be have cleaned up on probe exit.
3066 */
3067 if (!atomic_read(&pdev->enable_cnt))
3068 return;
3069
3070 base_vha = pci_get_drvdata(pdev);
3071 ha = base_vha->hw;
3072
3073 set_bit(UNLOADING, &base_vha->dpc_flags);
3074
3075 if (IS_QLAFX00(ha))
3076 qlafx00_driver_shutdown(base_vha, 20);
3077
3078 qla2x00_delete_all_vps(ha, base_vha);
3079
3080 if (IS_QLA8031(ha)) {
3081 ql_dbg(ql_dbg_p3p, base_vha, 0xb07e,
3082 "Clearing fcoe driver presence.\n");
3083 if (qla83xx_clear_drv_presence(base_vha) != QLA_SUCCESS)
3084 ql_dbg(ql_dbg_p3p, base_vha, 0xb079,
3085 "Error while clearing DRV-Presence.\n");
3086 }
3087
3088 qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
3089
3090 qla2x00_dfs_remove(base_vha);
3091
3092 qla84xx_put_chip(base_vha);
3093
3094 /* Disable timer */
3095 if (base_vha->timer_active)
3096 qla2x00_stop_timer(base_vha);
3097
3098 base_vha->flags.online = 0;
3099
3100 qla2x00_destroy_deferred_work(ha);
3101
3102 qlt_remove_target(ha, base_vha);
3103
3104 qla2x00_free_sysfs_attr(base_vha, true);
3105
3106 fc_remove_host(base_vha->host);
3107
3108 scsi_remove_host(base_vha->host);
3109
3110 qla2x00_free_device(base_vha);
3111
3112 scsi_host_put(base_vha->host);
3113
3114 qla2x00_clear_drv_active(base_vha);
3115
3116 qla2x00_unmap_iobases(ha);
3100 3117
3101 pci_release_selected_regions(ha->pdev, ha->bars); 3118 pci_release_selected_regions(ha->pdev, ha->bars);
3102 kfree(ha); 3119 kfree(ha);
@@ -3118,9 +3135,8 @@ qla2x00_free_device(scsi_qla_host_t *vha)
3118 if (vha->timer_active) 3135 if (vha->timer_active)
3119 qla2x00_stop_timer(vha); 3136 qla2x00_stop_timer(vha);
3120 3137
3121 qla2x00_stop_dpc_thread(vha);
3122
3123 qla25xx_delete_queues(vha); 3138 qla25xx_delete_queues(vha);
3139
3124 if (ha->flags.fce_enabled) 3140 if (ha->flags.fce_enabled)
3125 qla2x00_disable_fce_trace(vha, NULL, NULL); 3141 qla2x00_disable_fce_trace(vha, NULL, NULL);
3126 3142