diff options
author | Lalit Chandivade <lalit.chandivade@qlogic.com> | 2011-12-16 04:58:55 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-01-10 18:01:22 -0500 |
commit | 4a4bc2e90c1c689bf929914256310361d4012df1 (patch) | |
tree | c36a9276e0803b4765f19761b7cd23e876072b3b /drivers/scsi | |
parent | 00c4a09bb0840457f5f8f5753a562e5e19a91baf (diff) |
[SCSI] qla4xxx: cleanup, make qla4xxx_build_ddb_list short
Make qla4xxx_build_ddb_list shorter by adding more helper functions.
Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qla4xxx/ql4_os.c | 399 |
1 files changed, 237 insertions, 162 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c index ec393a00c038..87e3699d7ea2 100644 --- a/drivers/scsi/qla4xxx/ql4_os.c +++ b/drivers/scsi/qla4xxx/ql4_os.c | |||
@@ -2078,7 +2078,7 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha) | |||
2078 | } | 2078 | } |
2079 | } | 2079 | } |
2080 | 2080 | ||
2081 | void qla4xxx_check_relogin_flash_ddb(struct iscsi_cls_session *cls_sess) | 2081 | static void qla4xxx_check_relogin_flash_ddb(struct iscsi_cls_session *cls_sess) |
2082 | { | 2082 | { |
2083 | struct iscsi_session *sess; | 2083 | struct iscsi_session *sess; |
2084 | struct ddb_entry *ddb_entry; | 2084 | struct ddb_entry *ddb_entry; |
@@ -3826,16 +3826,14 @@ exit_check: | |||
3826 | return ret; | 3826 | return ret; |
3827 | } | 3827 | } |
3828 | 3828 | ||
3829 | static void qla4xxx_free_nt_list(struct list_head *list_nt) | 3829 | static void qla4xxx_free_ddb_list(struct list_head *list_ddb) |
3830 | { | 3830 | { |
3831 | struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp; | 3831 | struct qla_ddb_index *ddb_idx, *ddb_idx_tmp; |
3832 | 3832 | ||
3833 | /* Free up the normaltargets list */ | 3833 | list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, list_ddb, list) { |
3834 | list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) { | 3834 | list_del_init(&ddb_idx->list); |
3835 | list_del_init(&nt_ddb_idx->list); | 3835 | vfree(ddb_idx); |
3836 | vfree(nt_ddb_idx); | ||
3837 | } | 3836 | } |
3838 | |||
3839 | } | 3837 | } |
3840 | 3838 | ||
3841 | static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha, | 3839 | static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha, |
@@ -3934,7 +3932,6 @@ static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha) | |||
3934 | ip_state == IP_ADDRSTATE_DEPRICATED || | 3932 | ip_state == IP_ADDRSTATE_DEPRICATED || |
3935 | ip_state == IP_ADDRSTATE_DISABLING) | 3933 | ip_state == IP_ADDRSTATE_DISABLING) |
3936 | ip_idx[idx] = -1; | 3934 | ip_idx[idx] = -1; |
3937 | |||
3938 | } | 3935 | } |
3939 | 3936 | ||
3940 | /* Break if all IP states checked */ | 3937 | /* Break if all IP states checked */ |
@@ -3947,52 +3944,34 @@ static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha) | |||
3947 | } while (time_after(wtime, jiffies)); | 3944 | } while (time_after(wtime, jiffies)); |
3948 | } | 3945 | } |
3949 | 3946 | ||
3950 | void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset) | 3947 | static void qla4xxx_build_st_list(struct scsi_qla_host *ha, |
3948 | struct list_head *list_st) | ||
3951 | { | 3949 | { |
3950 | struct qla_ddb_index *st_ddb_idx; | ||
3952 | int max_ddbs; | 3951 | int max_ddbs; |
3952 | int fw_idx_size; | ||
3953 | struct dev_db_entry *fw_ddb_entry; | ||
3954 | dma_addr_t fw_ddb_dma; | ||
3953 | int ret; | 3955 | int ret; |
3954 | uint32_t idx = 0, next_idx = 0; | 3956 | uint32_t idx = 0, next_idx = 0; |
3955 | uint32_t state = 0, conn_err = 0; | 3957 | uint32_t state = 0, conn_err = 0; |
3956 | uint16_t conn_id; | 3958 | uint16_t conn_id = 0; |
3957 | struct dev_db_entry *fw_ddb_entry; | ||
3958 | struct ddb_entry *ddb_entry = NULL; | ||
3959 | dma_addr_t fw_ddb_dma; | ||
3960 | struct iscsi_cls_session *cls_sess; | ||
3961 | struct iscsi_session *sess; | ||
3962 | struct iscsi_cls_conn *cls_conn; | ||
3963 | struct iscsi_endpoint *ep; | ||
3964 | uint16_t cmds_max = 32, tmo = 0; | ||
3965 | uint32_t initial_cmdsn = 0; | ||
3966 | struct list_head list_st, list_nt; /* List of sendtargets */ | ||
3967 | struct qla_ddb_index *st_ddb_idx, *st_ddb_idx_tmp; | ||
3968 | int fw_idx_size; | ||
3969 | unsigned long wtime; | ||
3970 | struct qla_ddb_index *nt_ddb_idx; | ||
3971 | |||
3972 | if (!test_bit(AF_LINK_UP, &ha->flags)) { | ||
3973 | set_bit(AF_BUILD_DDB_LIST, &ha->flags); | ||
3974 | ha->is_reset = is_reset; | ||
3975 | return; | ||
3976 | } | ||
3977 | max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : | ||
3978 | MAX_DEV_DB_ENTRIES; | ||
3979 | 3959 | ||
3980 | fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, | 3960 | fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, |
3981 | &fw_ddb_dma); | 3961 | &fw_ddb_dma); |
3982 | if (fw_ddb_entry == NULL) { | 3962 | if (fw_ddb_entry == NULL) { |
3983 | DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n")); | 3963 | DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n")); |
3984 | goto exit_ddb_list; | 3964 | goto exit_st_list; |
3985 | } | 3965 | } |
3986 | 3966 | ||
3987 | INIT_LIST_HEAD(&list_st); | 3967 | max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : |
3988 | INIT_LIST_HEAD(&list_nt); | 3968 | MAX_DEV_DB_ENTRIES; |
3989 | fw_idx_size = sizeof(struct qla_ddb_index); | 3969 | fw_idx_size = sizeof(struct qla_ddb_index); |
3990 | 3970 | ||
3991 | for (idx = 0; idx < max_ddbs; idx = next_idx) { | 3971 | for (idx = 0; idx < max_ddbs; idx = next_idx) { |
3992 | ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, | 3972 | ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, fw_ddb_dma, |
3993 | fw_ddb_dma, NULL, | 3973 | NULL, &next_idx, &state, |
3994 | &next_idx, &state, &conn_err, | 3974 | &conn_err, NULL, &conn_id); |
3995 | NULL, &conn_id); | ||
3996 | if (ret == QLA_ERROR) | 3975 | if (ret == QLA_ERROR) |
3997 | break; | 3976 | break; |
3998 | 3977 | ||
@@ -4009,59 +3988,155 @@ void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset) | |||
4009 | 3988 | ||
4010 | st_ddb_idx->fw_ddb_idx = idx; | 3989 | st_ddb_idx->fw_ddb_idx = idx; |
4011 | 3990 | ||
4012 | list_add_tail(&st_ddb_idx->list, &list_st); | 3991 | list_add_tail(&st_ddb_idx->list, list_st); |
4013 | continue_next_st: | 3992 | continue_next_st: |
4014 | if (next_idx == 0) | 3993 | if (next_idx == 0) |
4015 | break; | 3994 | break; |
4016 | } | 3995 | } |
4017 | 3996 | ||
4018 | /* Before issuing conn open mbox, ensure all IPs states are configured | 3997 | exit_st_list: |
4019 | * Note, conn open fails if IPs are not configured | 3998 | if (fw_ddb_entry) |
3999 | dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma); | ||
4000 | } | ||
4001 | |||
4002 | /** | ||
4003 | * qla4xxx_remove_failed_ddb - Remove inactive or failed ddb from list | ||
4004 | * @ha: pointer to adapter structure | ||
4005 | * @list_ddb: List from which failed ddb to be removed | ||
4006 | * | ||
4007 | * Iterate over the list of DDBs and find and remove DDBs that are either in | ||
4008 | * no connection active state or failed state | ||
4009 | **/ | ||
4010 | static void qla4xxx_remove_failed_ddb(struct scsi_qla_host *ha, | ||
4011 | struct list_head *list_ddb) | ||
4012 | { | ||
4013 | struct qla_ddb_index *ddb_idx, *ddb_idx_tmp; | ||
4014 | uint32_t next_idx = 0; | ||
4015 | uint32_t state = 0, conn_err = 0; | ||
4016 | int ret; | ||
4017 | |||
4018 | list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, list_ddb, list) { | ||
4019 | ret = qla4xxx_get_fwddb_entry(ha, ddb_idx->fw_ddb_idx, | ||
4020 | NULL, 0, NULL, &next_idx, &state, | ||
4021 | &conn_err, NULL, NULL); | ||
4022 | if (ret == QLA_ERROR) | ||
4023 | continue; | ||
4024 | |||
4025 | if (state == DDB_DS_NO_CONNECTION_ACTIVE || | ||
4026 | state == DDB_DS_SESSION_FAILED) { | ||
4027 | list_del_init(&ddb_idx->list); | ||
4028 | vfree(ddb_idx); | ||
4029 | } | ||
4030 | } | ||
4031 | } | ||
4032 | |||
4033 | static int qla4xxx_sess_conn_setup(struct scsi_qla_host *ha, | ||
4034 | struct dev_db_entry *fw_ddb_entry, | ||
4035 | int is_reset) | ||
4036 | { | ||
4037 | struct iscsi_cls_session *cls_sess; | ||
4038 | struct iscsi_session *sess; | ||
4039 | struct iscsi_cls_conn *cls_conn; | ||
4040 | struct iscsi_endpoint *ep; | ||
4041 | uint16_t cmds_max = 32; | ||
4042 | uint16_t conn_id = 0; | ||
4043 | uint32_t initial_cmdsn = 0; | ||
4044 | int ret = QLA_SUCCESS; | ||
4045 | |||
4046 | struct ddb_entry *ddb_entry = NULL; | ||
4047 | |||
4048 | /* Create session object, with INVALID_ENTRY, | ||
4049 | * the targer_id would get set when we issue the login | ||
4020 | */ | 4050 | */ |
4021 | qla4xxx_wait_for_ip_configuration(ha); | 4051 | cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, ha->host, |
4052 | cmds_max, sizeof(struct ddb_entry), | ||
4053 | sizeof(struct ql4_task_data), | ||
4054 | initial_cmdsn, INVALID_ENTRY); | ||
4055 | if (!cls_sess) { | ||
4056 | ret = QLA_ERROR; | ||
4057 | goto exit_setup; | ||
4058 | } | ||
4022 | 4059 | ||
4023 | /* Go thru the STs and fire the sendtargets by issuing conn open mbx */ | 4060 | /* |
4024 | list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) { | 4061 | * so calling module_put function to decrement the |
4025 | qla4xxx_conn_open(ha, st_ddb_idx->fw_ddb_idx); | 4062 | * reference count. |
4063 | **/ | ||
4064 | module_put(qla4xxx_iscsi_transport.owner); | ||
4065 | sess = cls_sess->dd_data; | ||
4066 | ddb_entry = sess->dd_data; | ||
4067 | ddb_entry->sess = cls_sess; | ||
4068 | |||
4069 | cls_sess->recovery_tmo = ql4xsess_recovery_tmo; | ||
4070 | memcpy(&ddb_entry->fw_ddb_entry, fw_ddb_entry, | ||
4071 | sizeof(struct dev_db_entry)); | ||
4072 | |||
4073 | qla4xxx_setup_flash_ddb_entry(ha, ddb_entry); | ||
4074 | |||
4075 | cls_conn = iscsi_conn_setup(cls_sess, sizeof(struct qla_conn), conn_id); | ||
4076 | |||
4077 | if (!cls_conn) { | ||
4078 | ret = QLA_ERROR; | ||
4079 | goto exit_setup; | ||
4026 | } | 4080 | } |
4027 | 4081 | ||
4028 | /* Wait to ensure all sendtargets are done for min 12 sec wait */ | 4082 | ddb_entry->conn = cls_conn; |
4029 | tmo = ((ha->def_timeout < LOGIN_TOV) ? LOGIN_TOV : ha->def_timeout); | ||
4030 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
4031 | "Default time to wait for build ddb %d\n", tmo)); | ||
4032 | 4083 | ||
4033 | wtime = jiffies + (HZ * tmo); | 4084 | /* Setup ep, for displaying attributes in sysfs */ |
4034 | do { | 4085 | ep = qla4xxx_get_ep_fwdb(ha, fw_ddb_entry); |
4035 | list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, | 4086 | if (ep) { |
4036 | list) { | 4087 | ep->conn = cls_conn; |
4037 | ret = qla4xxx_get_fwddb_entry(ha, | 4088 | cls_conn->ep = ep; |
4038 | st_ddb_idx->fw_ddb_idx, | 4089 | } else { |
4039 | NULL, 0, NULL, &next_idx, | 4090 | DEBUG2(ql4_printk(KERN_ERR, ha, "Unable to get ep\n")); |
4040 | &state, &conn_err, NULL, | 4091 | ret = QLA_ERROR; |
4041 | NULL); | 4092 | goto exit_setup; |
4042 | if (ret == QLA_ERROR) | 4093 | } |
4043 | continue; | ||
4044 | 4094 | ||
4045 | if (state == DDB_DS_NO_CONNECTION_ACTIVE || | 4095 | /* Update sess/conn params */ |
4046 | state == DDB_DS_SESSION_FAILED) { | 4096 | qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, cls_conn); |
4047 | list_del_init(&st_ddb_idx->list); | ||
4048 | vfree(st_ddb_idx); | ||
4049 | } | ||
4050 | } | ||
4051 | schedule_timeout_uninterruptible(HZ / 10); | ||
4052 | } while (time_after(wtime, jiffies)); | ||
4053 | 4097 | ||
4054 | /* Free up the sendtargets list */ | 4098 | if (is_reset == RESET_ADAPTER) { |
4055 | list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) { | 4099 | iscsi_block_session(cls_sess); |
4056 | list_del_init(&st_ddb_idx->list); | 4100 | /* Use the relogin path to discover new devices |
4057 | vfree(st_ddb_idx); | 4101 | * by short-circuting the logic of setting |
4102 | * timer to relogin - instead set the flags | ||
4103 | * to initiate login right away. | ||
4104 | */ | ||
4105 | set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags); | ||
4106 | set_bit(DF_RELOGIN, &ddb_entry->flags); | ||
4058 | } | 4107 | } |
4059 | 4108 | ||
4109 | exit_setup: | ||
4110 | return ret; | ||
4111 | } | ||
4112 | |||
4113 | static void qla4xxx_build_nt_list(struct scsi_qla_host *ha, | ||
4114 | struct list_head *list_nt, int is_reset) | ||
4115 | { | ||
4116 | struct dev_db_entry *fw_ddb_entry; | ||
4117 | dma_addr_t fw_ddb_dma; | ||
4118 | int max_ddbs; | ||
4119 | int fw_idx_size; | ||
4120 | int ret; | ||
4121 | uint32_t idx = 0, next_idx = 0; | ||
4122 | uint32_t state = 0, conn_err = 0; | ||
4123 | uint16_t conn_id = 0; | ||
4124 | struct qla_ddb_index *nt_ddb_idx; | ||
4125 | |||
4126 | fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL, | ||
4127 | &fw_ddb_dma); | ||
4128 | if (fw_ddb_entry == NULL) { | ||
4129 | DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n")); | ||
4130 | goto exit_nt_list; | ||
4131 | } | ||
4132 | max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX : | ||
4133 | MAX_DEV_DB_ENTRIES; | ||
4134 | fw_idx_size = sizeof(struct qla_ddb_index); | ||
4135 | |||
4060 | for (idx = 0; idx < max_ddbs; idx = next_idx) { | 4136 | for (idx = 0; idx < max_ddbs; idx = next_idx) { |
4061 | ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, | 4137 | ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, fw_ddb_dma, |
4062 | fw_ddb_dma, NULL, | 4138 | NULL, &next_idx, &state, |
4063 | &next_idx, &state, &conn_err, | 4139 | &conn_err, NULL, &conn_id); |
4064 | NULL, &conn_id); | ||
4065 | if (ret == QLA_ERROR) | 4140 | if (ret == QLA_ERROR) |
4066 | break; | 4141 | break; |
4067 | 4142 | ||
@@ -4072,107 +4147,107 @@ continue_next_st: | |||
4072 | if (strlen((char *) fw_ddb_entry->iscsi_name) == 0) | 4147 | if (strlen((char *) fw_ddb_entry->iscsi_name) == 0) |
4073 | goto continue_next_nt; | 4148 | goto continue_next_nt; |
4074 | 4149 | ||
4075 | if (state == DDB_DS_NO_CONNECTION_ACTIVE || | 4150 | if (!(state == DDB_DS_NO_CONNECTION_ACTIVE || |
4076 | state == DDB_DS_SESSION_FAILED) { | 4151 | state == DDB_DS_SESSION_FAILED)) |
4077 | DEBUG2(ql4_printk(KERN_INFO, ha, | 4152 | goto continue_next_nt; |
4078 | "Adding DDB to session = 0x%x\n", | ||
4079 | idx)); | ||
4080 | if (is_reset == INIT_ADAPTER) { | ||
4081 | nt_ddb_idx = vmalloc(fw_idx_size); | ||
4082 | if (!nt_ddb_idx) | ||
4083 | break; | ||
4084 | |||
4085 | nt_ddb_idx->fw_ddb_idx = idx; | ||
4086 | |||
4087 | memcpy(&nt_ddb_idx->fw_ddb, fw_ddb_entry, | ||
4088 | sizeof(struct dev_db_entry)); | ||
4089 | |||
4090 | if (qla4xxx_is_flash_ddb_exists(ha, &list_nt, | ||
4091 | fw_ddb_entry) == QLA_SUCCESS) { | ||
4092 | vfree(nt_ddb_idx); | ||
4093 | goto continue_next_nt; | ||
4094 | } | ||
4095 | list_add_tail(&nt_ddb_idx->list, &list_nt); | ||
4096 | } else if (is_reset == RESET_ADAPTER) { | ||
4097 | if (qla4xxx_is_session_exists(ha, | ||
4098 | fw_ddb_entry) == QLA_SUCCESS) | ||
4099 | goto continue_next_nt; | ||
4100 | } | ||
4101 | 4153 | ||
4102 | /* Create session object, with INVALID_ENTRY, | 4154 | DEBUG2(ql4_printk(KERN_INFO, ha, |
4103 | * the targer_id would get set when we issue the login | 4155 | "Adding DDB to session = 0x%x\n", idx)); |
4104 | */ | 4156 | if (is_reset == INIT_ADAPTER) { |
4105 | cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, | 4157 | nt_ddb_idx = vmalloc(fw_idx_size); |
4106 | ha->host, cmds_max, | 4158 | if (!nt_ddb_idx) |
4107 | sizeof(struct ddb_entry), | 4159 | break; |
4108 | sizeof(struct ql4_task_data), | ||
4109 | initial_cmdsn, INVALID_ENTRY); | ||
4110 | if (!cls_sess) | ||
4111 | goto exit_ddb_list; | ||
4112 | 4160 | ||
4113 | /* | 4161 | nt_ddb_idx->fw_ddb_idx = idx; |
4114 | * iscsi_session_setup increments the driver reference | ||
4115 | * count which wouldn't let the driver to be unloaded. | ||
4116 | * so calling module_put function to decrement the | ||
4117 | * reference count. | ||
4118 | **/ | ||
4119 | module_put(qla4xxx_iscsi_transport.owner); | ||
4120 | sess = cls_sess->dd_data; | ||
4121 | ddb_entry = sess->dd_data; | ||
4122 | ddb_entry->sess = cls_sess; | ||
4123 | 4162 | ||
4124 | cls_sess->recovery_tmo = ql4xsess_recovery_tmo; | 4163 | memcpy(&nt_ddb_idx->fw_ddb, fw_ddb_entry, |
4125 | memcpy(&ddb_entry->fw_ddb_entry, fw_ddb_entry, | ||
4126 | sizeof(struct dev_db_entry)); | 4164 | sizeof(struct dev_db_entry)); |
4127 | 4165 | ||
4128 | qla4xxx_setup_flash_ddb_entry(ha, ddb_entry); | 4166 | if (qla4xxx_is_flash_ddb_exists(ha, list_nt, |
4129 | 4167 | fw_ddb_entry) == QLA_SUCCESS) { | |
4130 | cls_conn = iscsi_conn_setup(cls_sess, | 4168 | vfree(nt_ddb_idx); |
4131 | sizeof(struct qla_conn), | 4169 | goto continue_next_nt; |
4132 | conn_id); | ||
4133 | if (!cls_conn) | ||
4134 | goto exit_ddb_list; | ||
4135 | |||
4136 | ddb_entry->conn = cls_conn; | ||
4137 | |||
4138 | /* Setup ep, for displaying attributes in sysfs */ | ||
4139 | ep = qla4xxx_get_ep_fwdb(ha, fw_ddb_entry); | ||
4140 | if (ep) { | ||
4141 | ep->conn = cls_conn; | ||
4142 | cls_conn->ep = ep; | ||
4143 | } else { | ||
4144 | DEBUG2(ql4_printk(KERN_ERR, ha, | ||
4145 | "Unable to get ep\n")); | ||
4146 | } | ||
4147 | |||
4148 | /* Update sess/conn params */ | ||
4149 | qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, | ||
4150 | cls_conn); | ||
4151 | |||
4152 | if (is_reset == RESET_ADAPTER) { | ||
4153 | iscsi_block_session(cls_sess); | ||
4154 | /* Use the relogin path to discover new devices | ||
4155 | * by short-circuting the logic of setting | ||
4156 | * timer to relogin - instead set the flags | ||
4157 | * to initiate login right away. | ||
4158 | */ | ||
4159 | set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags); | ||
4160 | set_bit(DF_RELOGIN, &ddb_entry->flags); | ||
4161 | } | 4170 | } |
4171 | list_add_tail(&nt_ddb_idx->list, list_nt); | ||
4172 | } else if (is_reset == RESET_ADAPTER) { | ||
4173 | if (qla4xxx_is_session_exists(ha, fw_ddb_entry) == | ||
4174 | QLA_SUCCESS) | ||
4175 | goto continue_next_nt; | ||
4162 | } | 4176 | } |
4177 | |||
4178 | ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, is_reset); | ||
4179 | if (ret == QLA_ERROR) | ||
4180 | goto exit_nt_list; | ||
4181 | |||
4163 | continue_next_nt: | 4182 | continue_next_nt: |
4164 | if (next_idx == 0) | 4183 | if (next_idx == 0) |
4165 | break; | 4184 | break; |
4166 | } | 4185 | } |
4167 | exit_ddb_list: | 4186 | |
4168 | qla4xxx_free_nt_list(&list_nt); | 4187 | exit_nt_list: |
4169 | if (fw_ddb_entry) | 4188 | if (fw_ddb_entry) |
4170 | dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma); | 4189 | dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma); |
4190 | } | ||
4191 | |||
4192 | /** | ||
4193 | * qla4xxx_build_ddb_list - Build ddb list and setup sessions | ||
4194 | * @ha: pointer to adapter structure | ||
4195 | * @is_reset: Is this init path or reset path | ||
4196 | * | ||
4197 | * Create a list of sendtargets (st) from firmware DDBs, issue send targets | ||
4198 | * using connection open, then create the list of normal targets (nt) | ||
4199 | * from firmware DDBs. Based on the list of nt setup session and connection | ||
4200 | * objects. | ||
4201 | **/ | ||
4202 | void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset) | ||
4203 | { | ||
4204 | uint16_t tmo = 0; | ||
4205 | struct list_head list_st, list_nt; | ||
4206 | struct qla_ddb_index *st_ddb_idx, *st_ddb_idx_tmp; | ||
4207 | unsigned long wtime; | ||
4208 | |||
4209 | if (!test_bit(AF_LINK_UP, &ha->flags)) { | ||
4210 | set_bit(AF_BUILD_DDB_LIST, &ha->flags); | ||
4211 | ha->is_reset = is_reset; | ||
4212 | return; | ||
4213 | } | ||
4214 | |||
4215 | INIT_LIST_HEAD(&list_st); | ||
4216 | INIT_LIST_HEAD(&list_nt); | ||
4217 | |||
4218 | qla4xxx_build_st_list(ha, &list_st); | ||
4219 | |||
4220 | /* Before issuing conn open mbox, ensure all IPs states are configured | ||
4221 | * Note, conn open fails if IPs are not configured | ||
4222 | */ | ||
4223 | qla4xxx_wait_for_ip_configuration(ha); | ||
4224 | |||
4225 | /* Go thru the STs and fire the sendtargets by issuing conn open mbx */ | ||
4226 | list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) { | ||
4227 | qla4xxx_conn_open(ha, st_ddb_idx->fw_ddb_idx); | ||
4228 | } | ||
4229 | |||
4230 | /* Wait to ensure all sendtargets are done for min 12 sec wait */ | ||
4231 | tmo = ((ha->def_timeout < LOGIN_TOV) ? LOGIN_TOV : ha->def_timeout); | ||
4232 | DEBUG2(ql4_printk(KERN_INFO, ha, | ||
4233 | "Default time to wait for build ddb %d\n", tmo)); | ||
4234 | |||
4235 | wtime = jiffies + (HZ * tmo); | ||
4236 | do { | ||
4237 | qla4xxx_remove_failed_ddb(ha, &list_st); | ||
4238 | schedule_timeout_uninterruptible(HZ / 10); | ||
4239 | } while (time_after(wtime, jiffies)); | ||
4240 | |||
4241 | /* Free up the sendtargets list */ | ||
4242 | qla4xxx_free_ddb_list(&list_st); | ||
4243 | |||
4244 | qla4xxx_build_nt_list(ha, &list_nt, is_reset); | ||
4245 | |||
4246 | qla4xxx_free_ddb_list(&list_nt); | ||
4171 | 4247 | ||
4172 | qla4xxx_free_ddb_index(ha); | 4248 | qla4xxx_free_ddb_index(ha); |
4173 | } | 4249 | } |
4174 | 4250 | ||
4175 | |||
4176 | /** | 4251 | /** |
4177 | * qla4xxx_probe_adapter - callback function to probe HBA | 4252 | * qla4xxx_probe_adapter - callback function to probe HBA |
4178 | * @pdev: pointer to pci_dev structure | 4253 | * @pdev: pointer to pci_dev structure |