aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Christie <michaelc@cs.wisc.edu>2011-12-01 22:38:41 -0500
committerJames Bottomley <JBottomley@Parallels.com>2011-12-14 06:40:43 -0500
commit13483730a13bef372894aefcf73760f5c6c297be (patch)
treeb65e573e43e791b91e32a16cb67653354f0d33d0
parent44f747fff6e9f027a4866c1a6864e26ae7c510c8 (diff)
[SCSI] qla4xxx: fix flash/ddb support
With open-iscsi support, target entries persisted in the FLASH were not login. Added support in the qla4xxx driver to do the login on probe time to the target entries saved in the FLASH by user. With this changes upgrade to the new kernel with open-iscsi support in qla4xxx will ensure users original target entries login on driver load Signed-off-by: Manish Rangankar <manish.rangankar@qlogic.com> Signed-off-by: Ravi Anand <ravi.anand@qlogic.com> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h55
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h8
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h16
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c239
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c11
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c1081
-rw-r--r--drivers/scsi/qla4xxx/ql4_version.h2
7 files changed, 1315 insertions, 97 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index ace637bf254..fd5edc6e166 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -147,7 +147,7 @@
147#define ISCSI_ALIAS_SIZE 32 /* ISCSI Alias name size */ 147#define ISCSI_ALIAS_SIZE 32 /* ISCSI Alias name size */
148#define ISCSI_NAME_SIZE 0xE0 /* ISCSI Name size */ 148#define ISCSI_NAME_SIZE 0xE0 /* ISCSI Name size */
149 149
150#define QL4_SESS_RECOVERY_TMO 30 /* iSCSI session */ 150#define QL4_SESS_RECOVERY_TMO 120 /* iSCSI session */
151 /* recovery timeout */ 151 /* recovery timeout */
152 152
153#define LSDW(x) ((u32)((u64)(x))) 153#define LSDW(x) ((u32)((u64)(x)))
@@ -173,6 +173,8 @@
173#define ISNS_DEREG_TOV 5 173#define ISNS_DEREG_TOV 5
174#define HBA_ONLINE_TOV 30 174#define HBA_ONLINE_TOV 30
175#define DISABLE_ACB_TOV 30 175#define DISABLE_ACB_TOV 30
176#define IP_CONFIG_TOV 30
177#define LOGIN_TOV 12
176 178
177#define MAX_RESET_HA_RETRIES 2 179#define MAX_RESET_HA_RETRIES 2
178 180
@@ -240,6 +242,45 @@ struct ddb_entry {
240 242
241 uint16_t fw_ddb_index; /* DDB firmware index */ 243 uint16_t fw_ddb_index; /* DDB firmware index */
242 uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */ 244 uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */
245 uint16_t ddb_type;
246#define FLASH_DDB 0x01
247
248 struct dev_db_entry fw_ddb_entry;
249 int (*unblock_sess)(struct iscsi_cls_session *cls_session);
250 int (*ddb_change)(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
251 struct ddb_entry *ddb_entry, uint32_t state);
252
253 /* Driver Re-login */
254 unsigned long flags; /* DDB Flags */
255 uint16_t default_relogin_timeout; /* Max time to wait for
256 * relogin to complete */
257 atomic_t retry_relogin_timer; /* Min Time between relogins
258 * (4000 only) */
259 atomic_t relogin_timer; /* Max Time to wait for
260 * relogin to complete */
261 atomic_t relogin_retry_count; /* Num of times relogin has been
262 * retried */
263 uint32_t default_time2wait; /* Default Min time between
264 * relogins (+aens) */
265
266};
267
268struct qla_ddb_index {
269 struct list_head list;
270 uint16_t fw_ddb_idx;
271 struct dev_db_entry fw_ddb;
272};
273
274#define DDB_IPADDR_LEN 64
275
276struct ql4_tuple_ddb {
277 int port;
278 int tpgt;
279 char ip_addr[DDB_IPADDR_LEN];
280 char iscsi_name[ISCSI_NAME_SIZE];
281 uint16_t options;
282#define DDB_OPT_IPV6 0x0e0e
283#define DDB_OPT_IPV4 0x0f0f
243}; 284};
244 285
245/* 286/*
@@ -411,7 +452,7 @@ struct scsi_qla_host {
411#define AF_FW_RECOVERY 19 /* 0x00080000 */ 452#define AF_FW_RECOVERY 19 /* 0x00080000 */
412#define AF_EEH_BUSY 20 /* 0x00100000 */ 453#define AF_EEH_BUSY 20 /* 0x00100000 */
413#define AF_PCI_CHANNEL_IO_PERM_FAILURE 21 /* 0x00200000 */ 454#define AF_PCI_CHANNEL_IO_PERM_FAILURE 21 /* 0x00200000 */
414 455#define AF_BUILD_DDB_LIST 22 /* 0x00400000 */
415 unsigned long dpc_flags; 456 unsigned long dpc_flags;
416 457
417#define DPC_RESET_HA 1 /* 0x00000002 */ 458#define DPC_RESET_HA 1 /* 0x00000002 */
@@ -604,6 +645,7 @@ struct scsi_qla_host {
604 uint16_t bootload_minor; 645 uint16_t bootload_minor;
605 uint16_t bootload_patch; 646 uint16_t bootload_patch;
606 uint16_t bootload_build; 647 uint16_t bootload_build;
648 uint16_t def_timeout; /* Default login timeout */
607 649
608 uint32_t flash_state; 650 uint32_t flash_state;
609#define QLFLASH_WAITING 0 651#define QLFLASH_WAITING 0
@@ -623,6 +665,11 @@ struct scsi_qla_host {
623 uint16_t iscsi_pci_func_cnt; 665 uint16_t iscsi_pci_func_cnt;
624 uint8_t model_name[16]; 666 uint8_t model_name[16];
625 struct completion disable_acb_comp; 667 struct completion disable_acb_comp;
668 struct dma_pool *fw_ddb_dma_pool;
669#define DDB_DMA_BLOCK_SIZE 512
670 uint16_t pri_ddb_idx;
671 uint16_t sec_ddb_idx;
672 int is_reset;
626}; 673};
627 674
628struct ql4_task_data { 675struct ql4_task_data {
@@ -835,6 +882,10 @@ static inline int ql4xxx_reset_active(struct scsi_qla_host *ha)
835/*---------------------------------------------------------------------------*/ 882/*---------------------------------------------------------------------------*/
836 883
837/* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */ 884/* Defines for qla4xxx_initialize_adapter() and qla4xxx_recover_adapter() */
885
886#define INIT_ADAPTER 0
887#define RESET_ADAPTER 1
888
838#define PRESERVE_DDB_LIST 0 889#define PRESERVE_DDB_LIST 0
839#define REBUILD_DDB_LIST 1 890#define REBUILD_DDB_LIST 1
840 891
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index cbd5a20dbbd..4ac07f88252 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -12,6 +12,7 @@
12#define MAX_PRST_DEV_DB_ENTRIES 64 12#define MAX_PRST_DEV_DB_ENTRIES 64
13#define MIN_DISC_DEV_DB_ENTRY MAX_PRST_DEV_DB_ENTRIES 13#define MIN_DISC_DEV_DB_ENTRY MAX_PRST_DEV_DB_ENTRIES
14#define MAX_DEV_DB_ENTRIES 512 14#define MAX_DEV_DB_ENTRIES 512
15#define MAX_DEV_DB_ENTRIES_40XX 256
15 16
16/************************************************************************* 17/*************************************************************************
17 * 18 *
@@ -604,6 +605,13 @@ struct addr_ctrl_blk {
604 uint8_t res14[140]; /* 274-2FF */ 605 uint8_t res14[140]; /* 274-2FF */
605}; 606};
606 607
608#define IP_ADDR_COUNT 4 /* Total 4 IP address supported in one interface
609 * One IPv4, one IPv6 link local and 2 IPv6
610 */
611
612#define IP_STATE_MASK 0x0F000000
613#define IP_STATE_SHIFT 24
614
607struct init_fw_ctrl_blk { 615struct init_fw_ctrl_blk {
608 struct addr_ctrl_blk pri; 616 struct addr_ctrl_blk pri;
609/* struct addr_ctrl_blk sec;*/ 617/* struct addr_ctrl_blk sec;*/
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 160db9d5ea2..d0dd4b33020 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -13,7 +13,7 @@ struct iscsi_cls_conn;
13int qla4xxx_hw_reset(struct scsi_qla_host *ha); 13int qla4xxx_hw_reset(struct scsi_qla_host *ha);
14int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a); 14int ql4xxx_lock_drvr_wait(struct scsi_qla_host *a);
15int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb *srb); 15int qla4xxx_send_command_to_isp(struct scsi_qla_host *ha, struct srb *srb);
16int qla4xxx_initialize_adapter(struct scsi_qla_host *ha); 16int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset);
17int qla4xxx_soft_reset(struct scsi_qla_host *ha); 17int qla4xxx_soft_reset(struct scsi_qla_host *ha);
18irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id); 18irqreturn_t qla4xxx_intr_handler(int irq, void *dev_id);
19 19
@@ -153,10 +153,13 @@ int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
153 uint32_t *mbx_sts); 153 uint32_t *mbx_sts);
154int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t fw_ddb_index); 154int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t fw_ddb_index);
155int qla4xxx_send_passthru0(struct iscsi_task *task); 155int qla4xxx_send_passthru0(struct iscsi_task *task);
156void qla4xxx_free_ddb_index(struct scsi_qla_host *ha);
156int qla4xxx_get_mgmt_data(struct scsi_qla_host *ha, uint16_t fw_ddb_index, 157int qla4xxx_get_mgmt_data(struct scsi_qla_host *ha, uint16_t fw_ddb_index,
157 uint16_t stats_size, dma_addr_t stats_dma); 158 uint16_t stats_size, dma_addr_t stats_dma);
158void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, 159void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
159 struct ddb_entry *ddb_entry); 160 struct ddb_entry *ddb_entry);
161void qla4xxx_update_session_conn_fwddb_param(struct scsi_qla_host *ha,
162 struct ddb_entry *ddb_entry);
160int qla4xxx_bootdb_by_index(struct scsi_qla_host *ha, 163int qla4xxx_bootdb_by_index(struct scsi_qla_host *ha,
161 struct dev_db_entry *fw_ddb_entry, 164 struct dev_db_entry *fw_ddb_entry,
162 dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index); 165 dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index);
@@ -169,11 +172,22 @@ int qla4xxx_set_nvram(struct scsi_qla_host *ha, dma_addr_t nvram_dma,
169int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha, 172int qla4xxx_restore_factory_defaults(struct scsi_qla_host *ha,
170 uint32_t region, uint32_t field0, 173 uint32_t region, uint32_t field0,
171 uint32_t field1); 174 uint32_t field1);
175int qla4xxx_get_ddb_index(struct scsi_qla_host *ha, uint16_t *ddb_index);
176void qla4xxx_login_flash_ddb(struct iscsi_cls_session *cls_session);
177int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session);
178int qla4xxx_unblock_flash_ddb(struct iscsi_cls_session *cls_session);
179int qla4xxx_flash_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
180 struct ddb_entry *ddb_entry, uint32_t state);
181int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
182 struct ddb_entry *ddb_entry, uint32_t state);
183void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset);
172 184
173/* BSG Functions */ 185/* BSG Functions */
174int qla4xxx_bsg_request(struct bsg_job *bsg_job); 186int qla4xxx_bsg_request(struct bsg_job *bsg_job);
175int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job); 187int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job);
176 188
189void qla4xxx_arm_relogin_timer(struct ddb_entry *ddb_entry);
190
177extern int ql4xextended_error_logging; 191extern int ql4xextended_error_logging;
178extern int ql4xdontresethba; 192extern int ql4xdontresethba;
179extern int ql4xenablemsix; 193extern int ql4xenablemsix;
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 3075fbaef55..0497873a1dd 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -773,14 +773,14 @@ int qla4xxx_start_firmware(struct scsi_qla_host *ha)
773 * be freed so that when login happens from user space there are free DDB 773 * be freed so that when login happens from user space there are free DDB
774 * indices available. 774 * indices available.
775 **/ 775 **/
776static void qla4xxx_free_ddb_index(struct scsi_qla_host *ha) 776void qla4xxx_free_ddb_index(struct scsi_qla_host *ha)
777{ 777{
778 int max_ddbs; 778 int max_ddbs;
779 int ret; 779 int ret;
780 uint32_t idx = 0, next_idx = 0; 780 uint32_t idx = 0, next_idx = 0;
781 uint32_t state = 0, conn_err = 0; 781 uint32_t state = 0, conn_err = 0;
782 782
783 max_ddbs = is_qla40XX(ha) ? MAX_PRST_DEV_DB_ENTRIES : 783 max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
784 MAX_DEV_DB_ENTRIES; 784 MAX_DEV_DB_ENTRIES;
785 785
786 for (idx = 0; idx < max_ddbs; idx = next_idx) { 786 for (idx = 0; idx < max_ddbs; idx = next_idx) {
@@ -804,7 +804,6 @@ static void qla4xxx_free_ddb_index(struct scsi_qla_host *ha)
804 } 804 }
805} 805}
806 806
807
808/** 807/**
809 * qla4xxx_initialize_adapter - initiailizes hba 808 * qla4xxx_initialize_adapter - initiailizes hba
810 * @ha: Pointer to host adapter structure. 809 * @ha: Pointer to host adapter structure.
@@ -812,7 +811,7 @@ static void qla4xxx_free_ddb_index(struct scsi_qla_host *ha)
812 * This routine parforms all of the steps necessary to initialize the adapter. 811 * This routine parforms all of the steps necessary to initialize the adapter.
813 * 812 *
814 **/ 813 **/
815int qla4xxx_initialize_adapter(struct scsi_qla_host *ha) 814int qla4xxx_initialize_adapter(struct scsi_qla_host *ha, int is_reset)
816{ 815{
817 int status = QLA_ERROR; 816 int status = QLA_ERROR;
818 817
@@ -840,7 +839,8 @@ int qla4xxx_initialize_adapter(struct scsi_qla_host *ha)
840 if (status == QLA_ERROR) 839 if (status == QLA_ERROR)
841 goto exit_init_hba; 840 goto exit_init_hba;
842 841
843 qla4xxx_free_ddb_index(ha); 842 if (is_reset == RESET_ADAPTER)
843 qla4xxx_build_ddb_list(ha, is_reset);
844 844
845 set_bit(AF_ONLINE, &ha->flags); 845 set_bit(AF_ONLINE, &ha->flags);
846exit_init_hba: 846exit_init_hba:
@@ -855,38 +855,12 @@ exit_init_hba:
855 return status; 855 return status;
856} 856}
857 857
858/** 858int qla4xxx_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
859 * qla4xxx_process_ddb_changed - process ddb state change 859 struct ddb_entry *ddb_entry, uint32_t state)
860 * @ha - Pointer to host adapter structure.
861 * @fw_ddb_index - Firmware's device database index
862 * @state - Device state
863 *
864 * This routine processes a Decive Database Changed AEN Event.
865 **/
866int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
867 uint32_t state, uint32_t conn_err)
868{ 860{
869 struct ddb_entry * ddb_entry;
870 uint32_t old_fw_ddb_device_state; 861 uint32_t old_fw_ddb_device_state;
871 int status = QLA_ERROR; 862 int status = QLA_ERROR;
872 863
873 /* check for out of range index */
874 if (fw_ddb_index >= MAX_DDB_ENTRIES)
875 goto exit_ddb_event;
876
877 /* Get the corresponging ddb entry */
878 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, fw_ddb_index);
879 /* Device does not currently exist in our database. */
880 if (ddb_entry == NULL) {
881 ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n",
882 __func__, fw_ddb_index);
883
884 if (state == DDB_DS_NO_CONNECTION_ACTIVE)
885 clear_bit(fw_ddb_index, ha->ddb_idx_map);
886
887 goto exit_ddb_event;
888 }
889
890 old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state; 864 old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state;
891 DEBUG2(ql4_printk(KERN_INFO, ha, 865 DEBUG2(ql4_printk(KERN_INFO, ha,
892 "%s: DDB - old state = 0x%x, new state = 0x%x for " 866 "%s: DDB - old state = 0x%x, new state = 0x%x for "
@@ -900,9 +874,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
900 switch (state) { 874 switch (state) {
901 case DDB_DS_SESSION_ACTIVE: 875 case DDB_DS_SESSION_ACTIVE:
902 case DDB_DS_DISCOVERY: 876 case DDB_DS_DISCOVERY:
903 iscsi_conn_start(ddb_entry->conn); 877 ddb_entry->unblock_sess(ddb_entry->sess);
904 iscsi_conn_login_event(ddb_entry->conn,
905 ISCSI_CONN_STATE_LOGGED_IN);
906 qla4xxx_update_session_conn_param(ha, ddb_entry); 878 qla4xxx_update_session_conn_param(ha, ddb_entry);
907 status = QLA_SUCCESS; 879 status = QLA_SUCCESS;
908 break; 880 break;
@@ -936,9 +908,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
936 switch (state) { 908 switch (state) {
937 case DDB_DS_SESSION_ACTIVE: 909 case DDB_DS_SESSION_ACTIVE:
938 case DDB_DS_DISCOVERY: 910 case DDB_DS_DISCOVERY:
939 iscsi_conn_start(ddb_entry->conn); 911 ddb_entry->unblock_sess(ddb_entry->sess);
940 iscsi_conn_login_event(ddb_entry->conn,
941 ISCSI_CONN_STATE_LOGGED_IN);
942 qla4xxx_update_session_conn_param(ha, ddb_entry); 912 qla4xxx_update_session_conn_param(ha, ddb_entry);
943 status = QLA_SUCCESS; 913 status = QLA_SUCCESS;
944 break; 914 break;
@@ -954,7 +924,198 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
954 __func__)); 924 __func__));
955 break; 925 break;
956 } 926 }
927 return status;
928}
929
930void qla4xxx_arm_relogin_timer(struct ddb_entry *ddb_entry)
931{
932 /*
933 * This triggers a relogin. After the relogin_timer
934 * expires, the relogin gets scheduled. We must wait a
935 * minimum amount of time since receiving an 0x8014 AEN
936 * with failed device_state or a logout response before
937 * we can issue another relogin.
938 *
939 * Firmware pads this timeout: (time2wait +1).
940 * Driver retry to login should be longer than F/W.
941 * Otherwise F/W will fail
942 * set_ddb() mbx cmd with 0x4005 since it still
943 * counting down its time2wait.
944 */
945 atomic_set(&ddb_entry->relogin_timer, 0);
946 atomic_set(&ddb_entry->retry_relogin_timer,
947 ddb_entry->default_time2wait + 4);
948
949}
950
951int qla4xxx_flash_ddb_change(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
952 struct ddb_entry *ddb_entry, uint32_t state)
953{
954 uint32_t old_fw_ddb_device_state;
955 int status = QLA_ERROR;
956
957 old_fw_ddb_device_state = ddb_entry->fw_ddb_device_state;
958 DEBUG2(ql4_printk(KERN_INFO, ha,
959 "%s: DDB - old state = 0x%x, new state = 0x%x for "
960 "index [%d]\n", __func__,
961 ddb_entry->fw_ddb_device_state, state, fw_ddb_index));
962
963 ddb_entry->fw_ddb_device_state = state;
964
965 switch (old_fw_ddb_device_state) {
966 case DDB_DS_LOGIN_IN_PROCESS:
967 case DDB_DS_NO_CONNECTION_ACTIVE:
968 switch (state) {
969 case DDB_DS_SESSION_ACTIVE:
970 ddb_entry->unblock_sess(ddb_entry->sess);
971 qla4xxx_update_session_conn_fwddb_param(ha, ddb_entry);
972 status = QLA_SUCCESS;
973 break;
974 case DDB_DS_SESSION_FAILED:
975 iscsi_block_session(ddb_entry->sess);
976 if (!test_bit(DF_RELOGIN, &ddb_entry->flags))
977 qla4xxx_arm_relogin_timer(ddb_entry);
978 status = QLA_SUCCESS;
979 break;
980 }
981 break;
982 case DDB_DS_SESSION_ACTIVE:
983 switch (state) {
984 case DDB_DS_SESSION_FAILED:
985 iscsi_block_session(ddb_entry->sess);
986 if (!test_bit(DF_RELOGIN, &ddb_entry->flags))
987 qla4xxx_arm_relogin_timer(ddb_entry);
988 status = QLA_SUCCESS;
989 break;
990 }
991 break;
992 case DDB_DS_SESSION_FAILED:
993 switch (state) {
994 case DDB_DS_SESSION_ACTIVE:
995 ddb_entry->unblock_sess(ddb_entry->sess);
996 qla4xxx_update_session_conn_fwddb_param(ha, ddb_entry);
997 status = QLA_SUCCESS;
998 break;
999 case DDB_DS_SESSION_FAILED:
1000 if (!test_bit(DF_RELOGIN, &ddb_entry->flags))
1001 qla4xxx_arm_relogin_timer(ddb_entry);
1002 status = QLA_SUCCESS;
1003 break;
1004 }
1005 break;
1006 default:
1007 DEBUG2(ql4_printk(KERN_INFO, ha, "%s: Unknown Event\n",
1008 __func__));
1009 break;
1010 }
1011 return status;
1012}
1013
1014/**
1015 * qla4xxx_process_ddb_changed - process ddb state change
1016 * @ha - Pointer to host adapter structure.
1017 * @fw_ddb_index - Firmware's device database index
1018 * @state - Device state
1019 *
1020 * This routine processes a Decive Database Changed AEN Event.
1021 **/
1022int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha,
1023 uint32_t fw_ddb_index,
1024 uint32_t state, uint32_t conn_err)
1025{
1026 struct ddb_entry *ddb_entry;
1027 int status = QLA_ERROR;
1028
1029 /* check for out of range index */
1030 if (fw_ddb_index >= MAX_DDB_ENTRIES)
1031 goto exit_ddb_event;
1032
1033 /* Get the corresponging ddb entry */
1034 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, fw_ddb_index);
1035 /* Device does not currently exist in our database. */
1036 if (ddb_entry == NULL) {
1037 ql4_printk(KERN_ERR, ha, "%s: No ddb_entry at FW index [%d]\n",
1038 __func__, fw_ddb_index);
1039
1040 if (state == DDB_DS_NO_CONNECTION_ACTIVE)
1041 clear_bit(fw_ddb_index, ha->ddb_idx_map);
1042
1043 goto exit_ddb_event;
1044 }
1045
1046 ddb_entry->ddb_change(ha, fw_ddb_index, ddb_entry, state);
957 1047
958exit_ddb_event: 1048exit_ddb_event:
959 return status; 1049 return status;
960} 1050}
1051
1052/**
1053 * qla4xxx_login_flash_ddb - Login to target (DDB)
1054 * @cls_session: Pointer to the session to login
1055 *
1056 * This routine logins to the target.
1057 * Issues setddb and conn open mbx
1058 **/
1059void qla4xxx_login_flash_ddb(struct iscsi_cls_session *cls_session)
1060{
1061 struct iscsi_session *sess;
1062 struct ddb_entry *ddb_entry;
1063 struct scsi_qla_host *ha;
1064 struct dev_db_entry *fw_ddb_entry = NULL;
1065 dma_addr_t fw_ddb_dma;
1066 uint32_t mbx_sts = 0;
1067 int ret;
1068
1069 sess = cls_session->dd_data;
1070 ddb_entry = sess->dd_data;
1071 ha = ddb_entry->ha;
1072
1073 if (!test_bit(AF_LINK_UP, &ha->flags))
1074 return;
1075
1076 if (ddb_entry->ddb_type != FLASH_DDB) {
1077 DEBUG2(ql4_printk(KERN_INFO, ha,
1078 "Skipping login to non FLASH DB"));
1079 goto exit_login;
1080 }
1081
1082 fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,
1083 &fw_ddb_dma);
1084 if (fw_ddb_entry == NULL) {
1085 DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n"));
1086 goto exit_login;
1087 }
1088
1089 if (ddb_entry->fw_ddb_index == INVALID_ENTRY) {
1090 ret = qla4xxx_get_ddb_index(ha, &ddb_entry->fw_ddb_index);
1091 if (ret == QLA_ERROR)
1092 goto exit_login;
1093
1094 ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry;
1095 ha->tot_ddbs++;
1096 }
1097
1098 memcpy(fw_ddb_entry, &ddb_entry->fw_ddb_entry,
1099 sizeof(struct dev_db_entry));
1100 ddb_entry->sess->target_id = ddb_entry->fw_ddb_index;
1101
1102 ret = qla4xxx_set_ddb_entry(ha, ddb_entry->fw_ddb_index,
1103 fw_ddb_dma, &mbx_sts);
1104 if (ret == QLA_ERROR) {
1105 DEBUG2(ql4_printk(KERN_ERR, ha, "Set DDB failed\n"));
1106 goto exit_login;
1107 }
1108
1109 ddb_entry->fw_ddb_device_state = DDB_DS_LOGIN_IN_PROCESS;
1110 ret = qla4xxx_conn_open(ha, ddb_entry->fw_ddb_index);
1111 if (ret == QLA_ERROR) {
1112 ql4_printk(KERN_ERR, ha, "%s: Login failed: %s\n", __func__,
1113 sess->targetname);
1114 goto exit_login;
1115 }
1116
1117exit_login:
1118 if (fw_ddb_entry)
1119 dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);
1120}
1121
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 4c2b8487039..c2593782fbb 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -41,6 +41,16 @@ int qla4xxx_mailbox_command(struct scsi_qla_host *ha, uint8_t inCount,
41 return status; 41 return status;
42 } 42 }
43 43
44 if (is_qla40XX(ha)) {
45 if (test_bit(AF_HA_REMOVAL, &ha->flags)) {
46 DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: "
47 "prematurely completing mbx cmd as "
48 "adapter removal detected\n",
49 ha->host_no, __func__));
50 return status;
51 }
52 }
53
44 if (is_qla8022(ha)) { 54 if (is_qla8022(ha)) {
45 if (test_bit(AF_FW_RECOVERY, &ha->flags)) { 55 if (test_bit(AF_FW_RECOVERY, &ha->flags)) {
46 DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: " 56 DEBUG2(ql4_printk(KERN_WARNING, ha, "scsi%ld: %s: "
@@ -413,6 +423,7 @@ qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
413 memcpy(ha->name_string, init_fw_cb->iscsi_name, 423 memcpy(ha->name_string, init_fw_cb->iscsi_name,
414 min(sizeof(ha->name_string), 424 min(sizeof(ha->name_string),
415 sizeof(init_fw_cb->iscsi_name))); 425 sizeof(init_fw_cb->iscsi_name)));
426 ha->def_timeout = le16_to_cpu(init_fw_cb->def_timeout);
416 /*memcpy(ha->alias, init_fw_cb->Alias, 427 /*memcpy(ha->alias, init_fw_cb->Alias,
417 min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/ 428 min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/
418 429
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 30f31b127f3..95910c9b477 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -8,6 +8,7 @@
8#include <linux/slab.h> 8#include <linux/slab.h>
9#include <linux/blkdev.h> 9#include <linux/blkdev.h>
10#include <linux/iscsi_boot_sysfs.h> 10#include <linux/iscsi_boot_sysfs.h>
11#include <linux/inet.h>
11 12
12#include <scsi/scsi_tcq.h> 13#include <scsi/scsi_tcq.h>
13#include <scsi/scsicam.h> 14#include <scsi/scsicam.h>
@@ -31,6 +32,13 @@ static struct kmem_cache *srb_cachep;
31/* 32/*
32 * Module parameter information and variables 33 * Module parameter information and variables
33 */ 34 */
35int ql4xdisablesysfsboot = 1;
36module_param(ql4xdisablesysfsboot, int, S_IRUGO | S_IWUSR);
37MODULE_PARM_DESC(ql4xdisablesysfsboot,
38 "Set to disable exporting boot targets to sysfs\n"
39 " 0 - Export boot targets\n"
40 " 1 - Do not export boot targets (Default)");
41
34int ql4xdontresethba = 0; 42int ql4xdontresethba = 0;
35module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR); 43module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR);
36MODULE_PARM_DESC(ql4xdontresethba, 44MODULE_PARM_DESC(ql4xdontresethba,
@@ -63,7 +71,7 @@ static int ql4xsess_recovery_tmo = QL4_SESS_RECOVERY_TMO;
63module_param(ql4xsess_recovery_tmo, int, S_IRUGO); 71module_param(ql4xsess_recovery_tmo, int, S_IRUGO);
64MODULE_PARM_DESC(ql4xsess_recovery_tmo, 72MODULE_PARM_DESC(ql4xsess_recovery_tmo,
65 "Target Session Recovery Timeout.\n" 73 "Target Session Recovery Timeout.\n"
66 " Default: 30 sec."); 74 " Default: 120 sec.");
67 75
68static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha); 76static int qla4xxx_wait_for_hba_online(struct scsi_qla_host *ha);
69/* 77/*
@@ -415,7 +423,7 @@ static int qla4xxx_ep_poll(struct iscsi_endpoint *ep, int timeout_ms)
415 qla_ep = ep->dd_data; 423 qla_ep = ep->dd_data;
416 ha = to_qla_host(qla_ep->host); 424 ha = to_qla_host(qla_ep->host);
417 425
418 if (adapter_up(ha)) 426 if (adapter_up(ha) && !test_bit(AF_BUILD_DDB_LIST, &ha->flags))
419 ret = 1; 427 ret = 1;
420 428
421 return ret; 429 return ret;
@@ -975,6 +983,150 @@ static int qla4xxx_conn_get_param(struct iscsi_cls_conn *cls_conn,
975 983
976} 984}
977 985
986int qla4xxx_get_ddb_index(struct scsi_qla_host *ha, uint16_t *ddb_index)
987{
988 uint32_t mbx_sts = 0;
989 uint16_t tmp_ddb_index;
990 int ret;
991
992get_ddb_index:
993 tmp_ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES);
994
995 if (tmp_ddb_index >= MAX_DDB_ENTRIES) {
996 DEBUG2(ql4_printk(KERN_INFO, ha,
997 "Free DDB index not available\n"));
998 ret = QLA_ERROR;
999 goto exit_get_ddb_index;
1000 }
1001
1002 if (test_and_set_bit(tmp_ddb_index, ha->ddb_idx_map))
1003 goto get_ddb_index;
1004
1005 DEBUG2(ql4_printk(KERN_INFO, ha,
1006 "Found a free DDB index at %d\n", tmp_ddb_index));
1007 ret = qla4xxx_req_ddb_entry(ha, tmp_ddb_index, &mbx_sts);
1008 if (ret == QLA_ERROR) {
1009 if (mbx_sts == MBOX_STS_COMMAND_ERROR) {
1010 ql4_printk(KERN_INFO, ha,
1011 "DDB index = %d not available trying next\n",
1012 tmp_ddb_index);
1013 goto get_ddb_index;
1014 }
1015 DEBUG2(ql4_printk(KERN_INFO, ha,
1016 "Free FW DDB not available\n"));
1017 }
1018
1019 *ddb_index = tmp_ddb_index;
1020
1021exit_get_ddb_index:
1022 return ret;
1023}
1024
1025static int qla4xxx_match_ipaddress(struct scsi_qla_host *ha,
1026 struct ddb_entry *ddb_entry,
1027 char *existing_ipaddr,
1028 char *user_ipaddr)
1029{
1030 uint8_t dst_ipaddr[IPv6_ADDR_LEN];
1031 char formatted_ipaddr[DDB_IPADDR_LEN];
1032 int status = QLA_SUCCESS, ret = 0;
1033
1034 if (ddb_entry->fw_ddb_entry.options & DDB_OPT_IPV6_DEVICE) {
1035 ret = in6_pton(user_ipaddr, strlen(user_ipaddr), dst_ipaddr,
1036 '\0', NULL);
1037 if (ret == 0) {
1038 status = QLA_ERROR;
1039 goto out_match;
1040 }
1041 ret = sprintf(formatted_ipaddr, "%pI6", dst_ipaddr);
1042 } else {
1043 ret = in4_pton(user_ipaddr, strlen(user_ipaddr), dst_ipaddr,
1044 '\0', NULL);
1045 if (ret == 0) {
1046 status = QLA_ERROR;
1047 goto out_match;
1048 }
1049 ret = sprintf(formatted_ipaddr, "%pI4", dst_ipaddr);
1050 }
1051
1052 if (strcmp(existing_ipaddr, formatted_ipaddr))
1053 status = QLA_ERROR;
1054
1055out_match:
1056 return status;
1057}
1058
1059static int qla4xxx_match_fwdb_session(struct scsi_qla_host *ha,
1060 struct iscsi_cls_conn *cls_conn)
1061{
1062 int idx = 0, max_ddbs, rval;
1063 struct iscsi_cls_session *cls_sess = iscsi_conn_to_session(cls_conn);
1064 struct iscsi_session *sess, *existing_sess;
1065 struct iscsi_conn *conn, *existing_conn;
1066 struct ddb_entry *ddb_entry;
1067
1068 sess = cls_sess->dd_data;
1069 conn = cls_conn->dd_data;
1070
1071 if (sess->targetname == NULL ||
1072 conn->persistent_address == NULL ||
1073 conn->persistent_port == 0)
1074 return QLA_ERROR;
1075
1076 max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
1077 MAX_DEV_DB_ENTRIES;
1078
1079 for (idx = 0; idx < max_ddbs; idx++) {
1080 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);
1081 if (ddb_entry == NULL)
1082 continue;
1083
1084 if (ddb_entry->ddb_type != FLASH_DDB)
1085 continue;
1086
1087 existing_sess = ddb_entry->sess->dd_data;
1088 existing_conn = ddb_entry->conn->dd_data;
1089
1090 if (existing_sess->targetname == NULL ||
1091 existing_conn->persistent_address == NULL ||
1092 existing_conn->persistent_port == 0)
1093 continue;
1094
1095 DEBUG2(ql4_printk(KERN_INFO, ha,
1096 "IQN = %s User IQN = %s\n",
1097 existing_sess->targetname,
1098 sess->targetname));
1099
1100 DEBUG2(ql4_printk(KERN_INFO, ha,
1101 "IP = %s User IP = %s\n",
1102 existing_conn->persistent_address,
1103 conn->persistent_address));
1104
1105 DEBUG2(ql4_printk(KERN_INFO, ha,
1106 "Port = %d User Port = %d\n",
1107 existing_conn->persistent_port,
1108 conn->persistent_port));
1109
1110 if (strcmp(existing_sess->targetname, sess->targetname))
1111 continue;
1112 rval = qla4xxx_match_ipaddress(ha, ddb_entry,
1113 existing_conn->persistent_address,
1114 conn->persistent_address);
1115 if (rval == QLA_ERROR)
1116 continue;
1117 if (existing_conn->persistent_port != conn->persistent_port)
1118 continue;
1119 break;
1120 }
1121
1122 if (idx == max_ddbs)
1123 return QLA_ERROR;
1124
1125 DEBUG2(ql4_printk(KERN_INFO, ha,
1126 "Match found in fwdb sessions\n"));
1127 return QLA_SUCCESS;
1128}
1129
978static struct iscsi_cls_session * 1130static struct iscsi_cls_session *
979qla4xxx_session_create(struct iscsi_endpoint *ep, 1131qla4xxx_session_create(struct iscsi_endpoint *ep,
980 uint16_t cmds_max, uint16_t qdepth, 1132 uint16_t cmds_max, uint16_t qdepth,
@@ -984,8 +1136,7 @@ qla4xxx_session_create(struct iscsi_endpoint *ep,
984 struct scsi_qla_host *ha; 1136 struct scsi_qla_host *ha;
985 struct qla_endpoint *qla_ep; 1137 struct qla_endpoint *qla_ep;
986 struct ddb_entry *ddb_entry; 1138 struct ddb_entry *ddb_entry;
987 uint32_t ddb_index; 1139 uint16_t ddb_index;
988 uint32_t mbx_sts = 0;
989 struct iscsi_session *sess; 1140 struct iscsi_session *sess;
990 struct sockaddr *dst_addr; 1141 struct sockaddr *dst_addr;
991 int ret; 1142 int ret;
@@ -1000,32 +1151,9 @@ qla4xxx_session_create(struct iscsi_endpoint *ep,
1000 dst_addr = (struct sockaddr *)&qla_ep->dst_addr; 1151 dst_addr = (struct sockaddr *)&qla_ep->dst_addr;
1001 ha = to_qla_host(qla_ep->host); 1152 ha = to_qla_host(qla_ep->host);
1002 1153
1003get_ddb_index: 1154 ret = qla4xxx_get_ddb_index(ha, &ddb_index);
1004 ddb_index = find_first_zero_bit(ha->ddb_idx_map, MAX_DDB_ENTRIES); 1155 if (ret == QLA_ERROR)
1005
1006 if (ddb_index >= MAX_DDB_ENTRIES) {
1007 DEBUG2(ql4_printk(KERN_INFO, ha,
1008 "Free DDB index not available\n"));
1009 return NULL; 1156 return NULL;
1010 }
1011
1012 if (test_and_set_bit(ddb_index, ha->ddb_idx_map))
1013 goto get_ddb_index;
1014
1015 DEBUG2(ql4_printk(KERN_INFO, ha,
1016 "Found a free DDB index at %d\n", ddb_index));
1017 ret = qla4xxx_req_ddb_entry(ha, ddb_index, &mbx_sts);
1018 if (ret == QLA_ERROR) {
1019 if (mbx_sts == MBOX_STS_COMMAND_ERROR) {
1020 ql4_printk(KERN_INFO, ha,
1021 "DDB index = %d not available trying next\n",
1022 ddb_index);
1023 goto get_ddb_index;
1024 }
1025 DEBUG2(ql4_printk(KERN_INFO, ha,
1026 "Free FW DDB not available\n"));
1027 return NULL;
1028 }
1029 1157
1030 cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, qla_ep->host, 1158 cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport, qla_ep->host,
1031 cmds_max, sizeof(struct ddb_entry), 1159 cmds_max, sizeof(struct ddb_entry),
@@ -1040,6 +1168,8 @@ get_ddb_index:
1040 ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE; 1168 ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE;
1041 ddb_entry->ha = ha; 1169 ddb_entry->ha = ha;
1042 ddb_entry->sess = cls_sess; 1170 ddb_entry->sess = cls_sess;
1171 ddb_entry->unblock_sess = qla4xxx_unblock_ddb;
1172 ddb_entry->ddb_change = qla4xxx_ddb_change;
1043 cls_sess->recovery_tmo = ql4xsess_recovery_tmo; 1173 cls_sess->recovery_tmo = ql4xsess_recovery_tmo;
1044 ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry; 1174 ha->fw_ddb_index_map[ddb_entry->fw_ddb_index] = ddb_entry;
1045 ha->tot_ddbs++; 1175 ha->tot_ddbs++;
@@ -1109,7 +1239,7 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn)
1109 struct iscsi_session *sess; 1239 struct iscsi_session *sess;
1110 struct ddb_entry *ddb_entry; 1240 struct ddb_entry *ddb_entry;
1111 struct scsi_qla_host *ha; 1241 struct scsi_qla_host *ha;
1112 struct dev_db_entry *fw_ddb_entry; 1242 struct dev_db_entry *fw_ddb_entry = NULL;
1113 dma_addr_t fw_ddb_entry_dma; 1243 dma_addr_t fw_ddb_entry_dma;
1114 uint32_t mbx_sts = 0; 1244 uint32_t mbx_sts = 0;
1115 int ret = 0; 1245 int ret = 0;
@@ -1120,12 +1250,25 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn)
1120 ddb_entry = sess->dd_data; 1250 ddb_entry = sess->dd_data;
1121 ha = ddb_entry->ha; 1251 ha = ddb_entry->ha;
1122 1252
1253 /* Check if we have matching FW DDB, if yes then do not
1254 * login to this target. This could cause target to logout previous
1255 * connection
1256 */
1257 ret = qla4xxx_match_fwdb_session(ha, cls_conn);
1258 if (ret == QLA_SUCCESS) {
1259 ql4_printk(KERN_INFO, ha,
1260 "Session already exist in FW.\n");
1261 ret = -EEXIST;
1262 goto exit_conn_start;
1263 }
1264
1123 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 1265 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1124 &fw_ddb_entry_dma, GFP_KERNEL); 1266 &fw_ddb_entry_dma, GFP_KERNEL);
1125 if (!fw_ddb_entry) { 1267 if (!fw_ddb_entry) {
1126 ql4_printk(KERN_ERR, ha, 1268 ql4_printk(KERN_ERR, ha,
1127 "%s: Unable to allocate dma buffer\n", __func__); 1269 "%s: Unable to allocate dma buffer\n", __func__);
1128 return -ENOMEM; 1270 ret = -ENOMEM;
1271 goto exit_conn_start;
1129 } 1272 }
1130 1273
1131 ret = qla4xxx_set_param_ddbentry(ha, ddb_entry, cls_conn, &mbx_sts); 1274 ret = qla4xxx_set_param_ddbentry(ha, ddb_entry, cls_conn, &mbx_sts);
@@ -1138,9 +1281,7 @@ static int qla4xxx_conn_start(struct iscsi_cls_conn *cls_conn)
1138 if (mbx_sts) 1281 if (mbx_sts)
1139 if (ddb_entry->fw_ddb_device_state == 1282 if (ddb_entry->fw_ddb_device_state ==
1140 DDB_DS_SESSION_ACTIVE) { 1283 DDB_DS_SESSION_ACTIVE) {
1141 iscsi_conn_start(ddb_entry->conn); 1284 ddb_entry->unblock_sess(ddb_entry->sess);
1142 iscsi_conn_login_event(ddb_entry->conn,
1143 ISCSI_CONN_STATE_LOGGED_IN);
1144 goto exit_set_param; 1285 goto exit_set_param;
1145 } 1286 }
1146 1287
@@ -1167,8 +1308,9 @@ exit_set_param:
1167 ret = 0; 1308 ret = 0;
1168 1309
1169exit_conn_start: 1310exit_conn_start:
1170 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 1311 if (fw_ddb_entry)
1171 fw_ddb_entry, fw_ddb_entry_dma); 1312 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1313 fw_ddb_entry, fw_ddb_entry_dma);
1172 return ret; 1314 return ret;
1173} 1315}
1174 1316
@@ -1344,6 +1486,101 @@ static int qla4xxx_task_xmit(struct iscsi_task *task)
1344 return -ENOSYS; 1486 return -ENOSYS;
1345} 1487}
1346 1488
1489static void qla4xxx_copy_fwddb_param(struct scsi_qla_host *ha,
1490 struct dev_db_entry *fw_ddb_entry,
1491 struct iscsi_cls_session *cls_sess,
1492 struct iscsi_cls_conn *cls_conn)
1493{
1494 int buflen = 0;
1495 struct iscsi_session *sess;
1496 struct iscsi_conn *conn;
1497 char ip_addr[DDB_IPADDR_LEN];
1498 uint16_t options = 0;
1499
1500 sess = cls_sess->dd_data;
1501 conn = cls_conn->dd_data;
1502
1503 conn->max_recv_dlength = BYTE_UNITS *
1504 le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len);
1505
1506 conn->max_xmit_dlength = BYTE_UNITS *
1507 le16_to_cpu(fw_ddb_entry->iscsi_max_snd_data_seg_len);
1508
1509 sess->initial_r2t_en =
1510 (BIT_10 & le16_to_cpu(fw_ddb_entry->iscsi_options));
1511
1512 sess->max_r2t = le16_to_cpu(fw_ddb_entry->iscsi_max_outsnd_r2t);
1513
1514 sess->imm_data_en = (BIT_11 & le16_to_cpu(fw_ddb_entry->iscsi_options));
1515
1516 sess->first_burst = BYTE_UNITS *
1517 le16_to_cpu(fw_ddb_entry->iscsi_first_burst_len);
1518
1519 sess->max_burst = BYTE_UNITS *
1520 le16_to_cpu(fw_ddb_entry->iscsi_max_burst_len);
1521
1522 sess->time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait);
1523
1524 sess->time2retain = le16_to_cpu(fw_ddb_entry->iscsi_def_time2retain);
1525
1526 conn->persistent_port = le16_to_cpu(fw_ddb_entry->port);
1527
1528 sess->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);
1529
1530 options = le16_to_cpu(fw_ddb_entry->options);
1531 if (options & DDB_OPT_IPV6_DEVICE)
1532 sprintf(ip_addr, "%pI6", fw_ddb_entry->ip_addr);
1533 else
1534 sprintf(ip_addr, "%pI4", fw_ddb_entry->ip_addr);
1535
1536 iscsi_set_param(cls_conn, ISCSI_PARAM_TARGET_NAME,
1537 (char *)fw_ddb_entry->iscsi_name, buflen);
1538 iscsi_set_param(cls_conn, ISCSI_PARAM_INITIATOR_NAME,
1539 (char *)ha->name_string, buflen);
1540 iscsi_set_param(cls_conn, ISCSI_PARAM_PERSISTENT_ADDRESS,
1541 (char *)ip_addr, buflen);
1542}
1543
1544void qla4xxx_update_session_conn_fwddb_param(struct scsi_qla_host *ha,
1545 struct ddb_entry *ddb_entry)
1546{
1547 struct iscsi_cls_session *cls_sess;
1548 struct iscsi_cls_conn *cls_conn;
1549 uint32_t ddb_state;
1550 dma_addr_t fw_ddb_entry_dma;
1551 struct dev_db_entry *fw_ddb_entry;
1552
1553 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1554 &fw_ddb_entry_dma, GFP_KERNEL);
1555 if (!fw_ddb_entry) {
1556 ql4_printk(KERN_ERR, ha,
1557 "%s: Unable to allocate dma buffer\n", __func__);
1558 goto exit_session_conn_fwddb_param;
1559 }
1560
1561 if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry,
1562 fw_ddb_entry_dma, NULL, NULL, &ddb_state,
1563 NULL, NULL, NULL) == QLA_ERROR) {
1564 DEBUG2(ql4_printk(KERN_ERR, ha, "scsi%ld: %s: failed "
1565 "get_ddb_entry for fw_ddb_index %d\n",
1566 ha->host_no, __func__,
1567 ddb_entry->fw_ddb_index));
1568 goto exit_session_conn_fwddb_param;
1569 }
1570
1571 cls_sess = ddb_entry->sess;
1572
1573 cls_conn = ddb_entry->conn;
1574
1575 /* Update params */
1576 qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess, cls_conn);
1577
1578exit_session_conn_fwddb_param:
1579 if (fw_ddb_entry)
1580 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1581 fw_ddb_entry, fw_ddb_entry_dma);
1582}
1583
1347void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha, 1584void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
1348 struct ddb_entry *ddb_entry) 1585 struct ddb_entry *ddb_entry)
1349{ 1586{
@@ -1360,7 +1597,7 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
1360 if (!fw_ddb_entry) { 1597 if (!fw_ddb_entry) {
1361 ql4_printk(KERN_ERR, ha, 1598 ql4_printk(KERN_ERR, ha,
1362 "%s: Unable to allocate dma buffer\n", __func__); 1599 "%s: Unable to allocate dma buffer\n", __func__);
1363 return; 1600 goto exit_session_conn_param;
1364 } 1601 }
1365 1602
1366 if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry, 1603 if (qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index, fw_ddb_entry,
@@ -1370,7 +1607,7 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
1370 "get_ddb_entry for fw_ddb_index %d\n", 1607 "get_ddb_entry for fw_ddb_index %d\n",
1371 ha->host_no, __func__, 1608 ha->host_no, __func__,
1372 ddb_entry->fw_ddb_index)); 1609 ddb_entry->fw_ddb_index));
1373 return; 1610 goto exit_session_conn_param;
1374 } 1611 }
1375 1612
1376 cls_sess = ddb_entry->sess; 1613 cls_sess = ddb_entry->sess;
@@ -1379,6 +1616,12 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
1379 cls_conn = ddb_entry->conn; 1616 cls_conn = ddb_entry->conn;
1380 conn = cls_conn->dd_data; 1617 conn = cls_conn->dd_data;
1381 1618
1619 /* Update timers after login */
1620 ddb_entry->default_relogin_timeout =
1621 le16_to_cpu(fw_ddb_entry->def_timeout);
1622 ddb_entry->default_time2wait =
1623 le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait);
1624
1382 /* Update params */ 1625 /* Update params */
1383 conn->max_recv_dlength = BYTE_UNITS * 1626 conn->max_recv_dlength = BYTE_UNITS *
1384 le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len); 1627 le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len);
@@ -1407,6 +1650,11 @@ void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
1407 1650
1408 memcpy(sess->initiatorname, ha->name_string, 1651 memcpy(sess->initiatorname, ha->name_string,
1409 min(sizeof(ha->name_string), sizeof(sess->initiatorname))); 1652 min(sizeof(ha->name_string), sizeof(sess->initiatorname)));
1653
1654exit_session_conn_param:
1655 if (fw_ddb_entry)
1656 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1657 fw_ddb_entry, fw_ddb_entry_dma);
1410} 1658}
1411 1659
1412/* 1660/*
@@ -1607,6 +1855,9 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha)
1607 vfree(ha->chap_list); 1855 vfree(ha->chap_list);
1608 ha->chap_list = NULL; 1856 ha->chap_list = NULL;
1609 1857
1858 if (ha->fw_ddb_dma_pool)
1859 dma_pool_destroy(ha->fw_ddb_dma_pool);
1860
1610 /* release io space registers */ 1861 /* release io space registers */
1611 if (is_qla8022(ha)) { 1862 if (is_qla8022(ha)) {
1612 if (ha->nx_pcibase) 1863 if (ha->nx_pcibase)
@@ -1689,6 +1940,16 @@ static int qla4xxx_mem_alloc(struct scsi_qla_host *ha)
1689 goto mem_alloc_error_exit; 1940 goto mem_alloc_error_exit;
1690 } 1941 }
1691 1942
1943 ha->fw_ddb_dma_pool = dma_pool_create("ql4_fw_ddb", &ha->pdev->dev,
1944 DDB_DMA_BLOCK_SIZE, 8, 0);
1945
1946 if (ha->fw_ddb_dma_pool == NULL) {
1947 ql4_printk(KERN_WARNING, ha,
1948 "%s: fw_ddb_dma_pool allocation failed..\n",
1949 __func__);
1950 goto mem_alloc_error_exit;
1951 }
1952
1692 return QLA_SUCCESS; 1953 return QLA_SUCCESS;
1693 1954
1694mem_alloc_error_exit: 1955mem_alloc_error_exit:
@@ -1800,6 +2061,60 @@ void qla4_8xxx_watchdog(struct scsi_qla_host *ha)
1800 } 2061 }
1801} 2062}
1802 2063
2064void qla4xxx_check_relogin_flash_ddb(struct iscsi_cls_session *cls_sess)
2065{
2066 struct iscsi_session *sess;
2067 struct ddb_entry *ddb_entry;
2068 struct scsi_qla_host *ha;
2069
2070 sess = cls_sess->dd_data;
2071 ddb_entry = sess->dd_data;
2072 ha = ddb_entry->ha;
2073
2074 if (!(ddb_entry->ddb_type == FLASH_DDB))
2075 return;
2076
2077 if (adapter_up(ha) && !test_bit(DF_RELOGIN, &ddb_entry->flags) &&
2078 !iscsi_is_session_online(cls_sess)) {
2079 if (atomic_read(&ddb_entry->retry_relogin_timer) !=
2080 INVALID_ENTRY) {
2081 if (atomic_read(&ddb_entry->retry_relogin_timer) ==
2082 0) {
2083 atomic_set(&ddb_entry->retry_relogin_timer,
2084 INVALID_ENTRY);
2085 set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags);
2086 set_bit(DF_RELOGIN, &ddb_entry->flags);
2087 DEBUG2(ql4_printk(KERN_INFO, ha,
2088 "%s: index [%d] login device\n",
2089 __func__, ddb_entry->fw_ddb_index));
2090 } else
2091 atomic_dec(&ddb_entry->retry_relogin_timer);
2092 }
2093 }
2094
2095 /* Wait for relogin to timeout */
2096 if (atomic_read(&ddb_entry->relogin_timer) &&
2097 (atomic_dec_and_test(&ddb_entry->relogin_timer) != 0)) {
2098 /*
2099 * If the relogin times out and the device is
2100 * still NOT ONLINE then try and relogin again.
2101 */
2102 if (!iscsi_is_session_online(cls_sess)) {
2103 /* Reset retry relogin timer */
2104 atomic_inc(&ddb_entry->relogin_retry_count);
2105 DEBUG2(ql4_printk(KERN_INFO, ha,
2106 "%s: index[%d] relogin timed out-retrying"
2107 " relogin (%d), retry (%d)\n", __func__,
2108 ddb_entry->fw_ddb_index,
2109 atomic_read(&ddb_entry->relogin_retry_count),
2110 ddb_entry->default_time2wait + 4));
2111 set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags);
2112 atomic_set(&ddb_entry->retry_relogin_timer,
2113 ddb_entry->default_time2wait + 4);
2114 }
2115 }
2116}
2117
1803/** 2118/**
1804 * qla4xxx_timer - checks every second for work to do. 2119 * qla4xxx_timer - checks every second for work to do.
1805 * @ha: Pointer to host adapter structure. 2120 * @ha: Pointer to host adapter structure.
@@ -1809,6 +2124,8 @@ static void qla4xxx_timer(struct scsi_qla_host *ha)
1809 int start_dpc = 0; 2124 int start_dpc = 0;
1810 uint16_t w; 2125 uint16_t w;
1811 2126
2127 iscsi_host_for_each_session(ha->host, qla4xxx_check_relogin_flash_ddb);
2128
1812 /* If we are in the middle of AER/EEH processing 2129 /* If we are in the middle of AER/EEH processing
1813 * skip any processing and reschedule the timer 2130 * skip any processing and reschedule the timer
1814 */ 2131 */
@@ -2078,7 +2395,12 @@ static void qla4xxx_fail_session(struct iscsi_cls_session *cls_session)
2078 sess = cls_session->dd_data; 2395 sess = cls_session->dd_data;
2079 ddb_entry = sess->dd_data; 2396 ddb_entry = sess->dd_data;
2080 ddb_entry->fw_ddb_device_state = DDB_DS_SESSION_FAILED; 2397 ddb_entry->fw_ddb_device_state = DDB_DS_SESSION_FAILED;
2081 iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); 2398
2399 if (ddb_entry->ddb_type == FLASH_DDB)
2400 iscsi_block_session(ddb_entry->sess);
2401 else
2402 iscsi_session_failure(cls_session->dd_data,
2403 ISCSI_ERR_CONN_FAILED);
2082} 2404}
2083 2405
2084/** 2406/**
@@ -2163,7 +2485,7 @@ recover_ha_init_adapter:
2163 2485
2164 /* NOTE: AF_ONLINE flag set upon successful completion of 2486 /* NOTE: AF_ONLINE flag set upon successful completion of
2165 * qla4xxx_initialize_adapter */ 2487 * qla4xxx_initialize_adapter */
2166 status = qla4xxx_initialize_adapter(ha); 2488 status = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
2167 } 2489 }
2168 2490
2169 /* Retry failed adapter initialization, if necessary 2491 /* Retry failed adapter initialization, if necessary
@@ -2245,17 +2567,108 @@ static void qla4xxx_relogin_devices(struct iscsi_cls_session *cls_session)
2245 iscsi_unblock_session(ddb_entry->sess); 2567 iscsi_unblock_session(ddb_entry->sess);
2246 } else { 2568 } else {
2247 /* Trigger relogin */ 2569 /* Trigger relogin */
2248 iscsi_session_failure(cls_session->dd_data, 2570 if (ddb_entry->ddb_type == FLASH_DDB) {
2249 ISCSI_ERR_CONN_FAILED); 2571 if (!test_bit(DF_RELOGIN, &ddb_entry->flags))
2572 qla4xxx_arm_relogin_timer(ddb_entry);
2573 } else
2574 iscsi_session_failure(cls_session->dd_data,
2575 ISCSI_ERR_CONN_FAILED);
2250 } 2576 }
2251 } 2577 }
2252} 2578}
2253 2579
2580int qla4xxx_unblock_flash_ddb(struct iscsi_cls_session *cls_session)
2581{
2582 struct iscsi_session *sess;
2583 struct ddb_entry *ddb_entry;
2584 struct scsi_qla_host *ha;
2585
2586 sess = cls_session->dd_data;
2587 ddb_entry = sess->dd_data;
2588 ha = ddb_entry->ha;
2589 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"
2590 " unblock session\n", ha->host_no, __func__,
2591 ddb_entry->fw_ddb_index);
2592
2593 iscsi_unblock_session(ddb_entry->sess);
2594
2595 /* Start scan target */
2596 if (test_bit(AF_ONLINE, &ha->flags)) {
2597 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"
2598 " start scan\n", ha->host_no, __func__,
2599 ddb_entry->fw_ddb_index);
2600 scsi_queue_work(ha->host, &ddb_entry->sess->scan_work);
2601 }
2602 return QLA_SUCCESS;
2603}
2604
2605int qla4xxx_unblock_ddb(struct iscsi_cls_session *cls_session)
2606{
2607 struct iscsi_session *sess;
2608 struct ddb_entry *ddb_entry;
2609 struct scsi_qla_host *ha;
2610
2611 sess = cls_session->dd_data;
2612 ddb_entry = sess->dd_data;
2613 ha = ddb_entry->ha;
2614 ql4_printk(KERN_INFO, ha, "scsi%ld: %s: ddb[%d]"
2615 " unblock user space session\n", ha->host_no, __func__,
2616 ddb_entry->fw_ddb_index);
2617 iscsi_conn_start(ddb_entry->conn);
2618 iscsi_conn_login_event(ddb_entry->conn,
2619 ISCSI_CONN_STATE_LOGGED_IN);
2620
2621 return QLA_SUCCESS;
2622}
2623
2254static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha) 2624static void qla4xxx_relogin_all_devices(struct scsi_qla_host *ha)
2255{ 2625{
2256 iscsi_host_for_each_session(ha->host, qla4xxx_relogin_devices); 2626 iscsi_host_for_each_session(ha->host, qla4xxx_relogin_devices);
2257} 2627}
2258 2628
2629static void qla4xxx_relogin_flash_ddb(struct iscsi_cls_session *cls_sess)
2630{
2631 uint16_t relogin_timer;
2632 struct iscsi_session *sess;
2633 struct ddb_entry *ddb_entry;
2634 struct scsi_qla_host *ha;
2635
2636 sess = cls_sess->dd_data;
2637 ddb_entry = sess->dd_data;
2638 ha = ddb_entry->ha;
2639
2640 relogin_timer = max(ddb_entry->default_relogin_timeout,
2641 (uint16_t)RELOGIN_TOV);
2642 atomic_set(&ddb_entry->relogin_timer, relogin_timer);
2643
2644 DEBUG2(ql4_printk(KERN_INFO, ha,
2645 "scsi%ld: Relogin index [%d]. TOV=%d\n", ha->host_no,
2646 ddb_entry->fw_ddb_index, relogin_timer));
2647
2648 qla4xxx_login_flash_ddb(cls_sess);
2649}
2650
2651static void qla4xxx_dpc_relogin(struct iscsi_cls_session *cls_sess)
2652{
2653 struct iscsi_session *sess;
2654 struct ddb_entry *ddb_entry;
2655 struct scsi_qla_host *ha;
2656
2657 sess = cls_sess->dd_data;
2658 ddb_entry = sess->dd_data;
2659 ha = ddb_entry->ha;
2660
2661 if (!(ddb_entry->ddb_type == FLASH_DDB))
2662 return;
2663
2664 if (test_and_clear_bit(DF_RELOGIN, &ddb_entry->flags) &&
2665 !iscsi_is_session_online(cls_sess)) {
2666 DEBUG2(ql4_printk(KERN_INFO, ha,
2667 "relogin issued\n"));
2668 qla4xxx_relogin_flash_ddb(cls_sess);
2669 }
2670}
2671
2259void qla4xxx_wake_dpc(struct scsi_qla_host *ha) 2672void qla4xxx_wake_dpc(struct scsi_qla_host *ha)
2260{ 2673{
2261 if (ha->dpc_thread) 2674 if (ha->dpc_thread)
@@ -2356,6 +2769,12 @@ dpc_post_reset_ha:
2356 if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags)) 2769 if (test_and_clear_bit(DPC_GET_DHCP_IP_ADDR, &ha->dpc_flags))
2357 qla4xxx_get_dhcp_ip_address(ha); 2770 qla4xxx_get_dhcp_ip_address(ha);
2358 2771
2772 /* ---- relogin device? --- */
2773 if (adapter_up(ha) &&
2774 test_and_clear_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags)) {
2775 iscsi_host_for_each_session(ha->host, qla4xxx_dpc_relogin);
2776 }
2777
2359 /* ---- link change? --- */ 2778 /* ---- link change? --- */
2360 if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) { 2779 if (test_and_clear_bit(DPC_LINK_CHANGED, &ha->dpc_flags)) {
2361 if (!test_bit(AF_LINK_UP, &ha->flags)) { 2780 if (!test_bit(AF_LINK_UP, &ha->flags)) {
@@ -2368,8 +2787,12 @@ dpc_post_reset_ha:
2368 * fatal error recovery. Therefore, the driver must 2787 * fatal error recovery. Therefore, the driver must
2369 * manually relogin to devices when recovering from 2788 * manually relogin to devices when recovering from
2370 * connection failures, logouts, expired KATO, etc. */ 2789 * connection failures, logouts, expired KATO, etc. */
2371 2790 if (test_and_clear_bit(AF_BUILD_DDB_LIST, &ha->flags)) {
2372 qla4xxx_relogin_all_devices(ha); 2791 qla4xxx_build_ddb_list(ha, ha->is_reset);
2792 iscsi_host_for_each_session(ha->host,
2793 qla4xxx_login_flash_ddb);
2794 } else
2795 qla4xxx_relogin_all_devices(ha);
2373 } 2796 }
2374 } 2797 }
2375} 2798}
@@ -2867,6 +3290,9 @@ static int get_fw_boot_info(struct scsi_qla_host *ha, uint16_t ddb_index[])
2867 " target ID %d\n", __func__, ddb_index[0], 3290 " target ID %d\n", __func__, ddb_index[0],
2868 ddb_index[1])); 3291 ddb_index[1]));
2869 3292
3293 ha->pri_ddb_idx = ddb_index[0];
3294 ha->sec_ddb_idx = ddb_index[1];
3295
2870exit_boot_info_free: 3296exit_boot_info_free:
2871 dma_free_coherent(&ha->pdev->dev, size, buf, buf_dma); 3297 dma_free_coherent(&ha->pdev->dev, size, buf, buf_dma);
2872exit_boot_info: 3298exit_boot_info:
@@ -3034,6 +3460,9 @@ static int qla4xxx_get_boot_info(struct scsi_qla_host *ha)
3034 return ret; 3460 return ret;
3035 } 3461 }
3036 3462
3463 if (ql4xdisablesysfsboot)
3464 return QLA_SUCCESS;
3465
3037 if (ddb_index[0] == 0xffff) 3466 if (ddb_index[0] == 0xffff)
3038 goto sec_target; 3467 goto sec_target;
3039 3468
@@ -3066,7 +3495,15 @@ static int qla4xxx_setup_boot_info(struct scsi_qla_host *ha)
3066 struct iscsi_boot_kobj *boot_kobj; 3495 struct iscsi_boot_kobj *boot_kobj;
3067 3496
3068 if (qla4xxx_get_boot_info(ha) != QLA_SUCCESS) 3497 if (qla4xxx_get_boot_info(ha) != QLA_SUCCESS)
3069 return 0; 3498 return QLA_ERROR;
3499
3500 if (ql4xdisablesysfsboot) {
3501 ql4_printk(KERN_INFO, ha,
3502 "%s: syfsboot disabled - driver will trigger login"
3503 "and publish session for discovery .\n", __func__);
3504 return QLA_SUCCESS;
3505 }
3506
3070 3507
3071 ha->boot_kset = iscsi_boot_create_host_kset(ha->host->host_no); 3508 ha->boot_kset = iscsi_boot_create_host_kset(ha->host->host_no);
3072 if (!ha->boot_kset) 3509 if (!ha->boot_kset)
@@ -3108,7 +3545,7 @@ static int qla4xxx_setup_boot_info(struct scsi_qla_host *ha)
3108 if (!boot_kobj) 3545 if (!boot_kobj)
3109 goto put_host; 3546 goto put_host;
3110 3547
3111 return 0; 3548 return QLA_SUCCESS;
3112 3549
3113put_host: 3550put_host:
3114 scsi_host_put(ha->host); 3551 scsi_host_put(ha->host);
@@ -3174,9 +3611,507 @@ static void qla4xxx_create_chap_list(struct scsi_qla_host *ha)
3174exit_chap_list: 3611exit_chap_list:
3175 dma_free_coherent(&ha->pdev->dev, chap_size, 3612 dma_free_coherent(&ha->pdev->dev, chap_size,
3176 chap_flash_data, chap_dma); 3613 chap_flash_data, chap_dma);
3177 return;
3178} 3614}
3179 3615
3616static void qla4xxx_get_param_ddb(struct ddb_entry *ddb_entry,
3617 struct ql4_tuple_ddb *tddb)
3618{
3619 struct scsi_qla_host *ha;
3620 struct iscsi_cls_session *cls_sess;
3621 struct iscsi_cls_conn *cls_conn;
3622 struct iscsi_session *sess;
3623 struct iscsi_conn *conn;
3624
3625 DEBUG2(printk(KERN_INFO "Func: %s\n", __func__));
3626 ha = ddb_entry->ha;
3627 cls_sess = ddb_entry->sess;
3628 sess = cls_sess->dd_data;
3629 cls_conn = ddb_entry->conn;
3630 conn = cls_conn->dd_data;
3631
3632 tddb->tpgt = sess->tpgt;
3633 tddb->port = conn->persistent_port;
3634 strncpy(tddb->iscsi_name, sess->targetname, ISCSI_NAME_SIZE);
3635 strncpy(tddb->ip_addr, conn->persistent_address, DDB_IPADDR_LEN);
3636}
3637
3638static void qla4xxx_convert_param_ddb(struct dev_db_entry *fw_ddb_entry,
3639 struct ql4_tuple_ddb *tddb)
3640{
3641 uint16_t options = 0;
3642
3643 tddb->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);
3644 memcpy(&tddb->iscsi_name[0], &fw_ddb_entry->iscsi_name[0],
3645 min(sizeof(tddb->iscsi_name), sizeof(fw_ddb_entry->iscsi_name)));
3646
3647 options = le16_to_cpu(fw_ddb_entry->options);
3648 if (options & DDB_OPT_IPV6_DEVICE)
3649 sprintf(tddb->ip_addr, "%pI6", fw_ddb_entry->ip_addr);
3650 else
3651 sprintf(tddb->ip_addr, "%pI4", fw_ddb_entry->ip_addr);
3652
3653 tddb->port = le16_to_cpu(fw_ddb_entry->port);
3654}
3655
3656static int qla4xxx_compare_tuple_ddb(struct scsi_qla_host *ha,
3657 struct ql4_tuple_ddb *old_tddb,
3658 struct ql4_tuple_ddb *new_tddb)
3659{
3660 if (strcmp(old_tddb->iscsi_name, new_tddb->iscsi_name))
3661 return QLA_ERROR;
3662
3663 if (strcmp(old_tddb->ip_addr, new_tddb->ip_addr))
3664 return QLA_ERROR;
3665
3666 if (old_tddb->port != new_tddb->port)
3667 return QLA_ERROR;
3668
3669 DEBUG2(ql4_printk(KERN_INFO, ha,
3670 "Match Found, fw[%d,%d,%s,%s], [%d,%d,%s,%s]",
3671 old_tddb->port, old_tddb->tpgt, old_tddb->ip_addr,
3672 old_tddb->iscsi_name, new_tddb->port, new_tddb->tpgt,
3673 new_tddb->ip_addr, new_tddb->iscsi_name));
3674
3675 return QLA_SUCCESS;
3676}
3677
3678static int qla4xxx_is_session_exists(struct scsi_qla_host *ha,
3679 struct dev_db_entry *fw_ddb_entry)
3680{
3681 struct ddb_entry *ddb_entry;
3682 struct ql4_tuple_ddb *fw_tddb = NULL;
3683 struct ql4_tuple_ddb *tmp_tddb = NULL;
3684 int idx;
3685 int ret = QLA_ERROR;
3686
3687 fw_tddb = vzalloc(sizeof(*fw_tddb));
3688 if (!fw_tddb) {
3689 DEBUG2(ql4_printk(KERN_WARNING, ha,
3690 "Memory Allocation failed.\n"));
3691 ret = QLA_SUCCESS;
3692 goto exit_check;
3693 }
3694
3695 tmp_tddb = vzalloc(sizeof(*tmp_tddb));
3696 if (!tmp_tddb) {
3697 DEBUG2(ql4_printk(KERN_WARNING, ha,
3698 "Memory Allocation failed.\n"));
3699 ret = QLA_SUCCESS;
3700 goto exit_check;
3701 }
3702
3703 qla4xxx_convert_param_ddb(fw_ddb_entry, fw_tddb);
3704
3705 for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) {
3706 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);
3707 if (ddb_entry == NULL)
3708 continue;
3709
3710 qla4xxx_get_param_ddb(ddb_entry, tmp_tddb);
3711 if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb)) {
3712 ret = QLA_SUCCESS; /* found */
3713 goto exit_check;
3714 }
3715 }
3716
3717exit_check:
3718 if (fw_tddb)
3719 vfree(fw_tddb);
3720 if (tmp_tddb)
3721 vfree(tmp_tddb);
3722 return ret;
3723}
3724
3725static int qla4xxx_is_flash_ddb_exists(struct scsi_qla_host *ha,
3726 struct list_head *list_nt,
3727 struct dev_db_entry *fw_ddb_entry)
3728{
3729 struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp;
3730 struct ql4_tuple_ddb *fw_tddb = NULL;
3731 struct ql4_tuple_ddb *tmp_tddb = NULL;
3732 int ret = QLA_ERROR;
3733
3734 fw_tddb = vzalloc(sizeof(*fw_tddb));
3735 if (!fw_tddb) {
3736 DEBUG2(ql4_printk(KERN_WARNING, ha,
3737 "Memory Allocation failed.\n"));
3738 ret = QLA_SUCCESS;
3739 goto exit_check;
3740 }
3741
3742 tmp_tddb = vzalloc(sizeof(*tmp_tddb));
3743 if (!tmp_tddb) {
3744 DEBUG2(ql4_printk(KERN_WARNING, ha,
3745 "Memory Allocation failed.\n"));
3746 ret = QLA_SUCCESS;
3747 goto exit_check;
3748 }
3749
3750 qla4xxx_convert_param_ddb(fw_ddb_entry, fw_tddb);
3751
3752 list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) {
3753 qla4xxx_convert_param_ddb(&nt_ddb_idx->fw_ddb, tmp_tddb);
3754 if (!qla4xxx_compare_tuple_ddb(ha, fw_tddb, tmp_tddb)) {
3755 ret = QLA_SUCCESS; /* found */
3756 goto exit_check;
3757 }
3758 }
3759
3760exit_check:
3761 if (fw_tddb)
3762 vfree(fw_tddb);
3763 if (tmp_tddb)
3764 vfree(tmp_tddb);
3765 return ret;
3766}
3767
3768static void qla4xxx_free_nt_list(struct list_head *list_nt)
3769{
3770 struct qla_ddb_index *nt_ddb_idx, *nt_ddb_idx_tmp;
3771
3772 /* Free up the normaltargets list */
3773 list_for_each_entry_safe(nt_ddb_idx, nt_ddb_idx_tmp, list_nt, list) {
3774 list_del_init(&nt_ddb_idx->list);
3775 vfree(nt_ddb_idx);
3776 }
3777
3778}
3779
3780static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha,
3781 struct dev_db_entry *fw_ddb_entry)
3782{
3783 struct iscsi_endpoint *ep;
3784 struct sockaddr_in *addr;
3785 struct sockaddr_in6 *addr6;
3786 struct sockaddr *dst_addr;
3787 char *ip;
3788
3789 /* TODO: need to destroy on unload iscsi_endpoint*/
3790 dst_addr = vmalloc(sizeof(*dst_addr));
3791 if (!dst_addr)
3792 return NULL;
3793
3794 if (fw_ddb_entry->options & DDB_OPT_IPV6_DEVICE) {
3795 dst_addr->sa_family = AF_INET6;
3796 addr6 = (struct sockaddr_in6 *)dst_addr;
3797 ip = (char *)&addr6->sin6_addr;
3798 memcpy(ip, fw_ddb_entry->ip_addr, IPv6_ADDR_LEN);
3799 addr6->sin6_port = htons(le16_to_cpu(fw_ddb_entry->port));
3800
3801 } else {
3802 dst_addr->sa_family = AF_INET;
3803 addr = (struct sockaddr_in *)dst_addr;
3804 ip = (char *)&addr->sin_addr;
3805 memcpy(ip, fw_ddb_entry->ip_addr, IP_ADDR_LEN);
3806 addr->sin_port = htons(le16_to_cpu(fw_ddb_entry->port));
3807 }
3808
3809 ep = qla4xxx_ep_connect(ha->host, dst_addr, 0);
3810 vfree(dst_addr);
3811 return ep;
3812}
3813
3814static int qla4xxx_verify_boot_idx(struct scsi_qla_host *ha, uint16_t idx)
3815{
3816 if (ql4xdisablesysfsboot)
3817 return QLA_SUCCESS;
3818 if (idx == ha->pri_ddb_idx || idx == ha->sec_ddb_idx)
3819 return QLA_ERROR;
3820 return QLA_SUCCESS;
3821}
3822
3823static void qla4xxx_setup_flash_ddb_entry(struct scsi_qla_host *ha,
3824 struct ddb_entry *ddb_entry)
3825{
3826 ddb_entry->ddb_type = FLASH_DDB;
3827 ddb_entry->fw_ddb_index = INVALID_ENTRY;
3828 ddb_entry->fw_ddb_device_state = DDB_DS_NO_CONNECTION_ACTIVE;
3829 ddb_entry->ha = ha;
3830 ddb_entry->unblock_sess = qla4xxx_unblock_flash_ddb;
3831 ddb_entry->ddb_change = qla4xxx_flash_ddb_change;
3832
3833 atomic_set(&ddb_entry->retry_relogin_timer, INVALID_ENTRY);
3834 atomic_set(&ddb_entry->relogin_timer, 0);
3835 atomic_set(&ddb_entry->relogin_retry_count, 0);
3836
3837 ddb_entry->default_relogin_timeout =
3838 le16_to_cpu(ddb_entry->fw_ddb_entry.def_timeout);
3839 ddb_entry->default_time2wait =
3840 le16_to_cpu(ddb_entry->fw_ddb_entry.iscsi_def_time2wait);
3841}
3842
3843static void qla4xxx_wait_for_ip_configuration(struct scsi_qla_host *ha)
3844{
3845 uint32_t idx = 0;
3846 uint32_t ip_idx[IP_ADDR_COUNT] = {0, 1, 2, 3}; /* 4 IP interfaces */
3847 uint32_t sts[MBOX_REG_COUNT];
3848 uint32_t ip_state;
3849 unsigned long wtime;
3850 int ret;
3851
3852 wtime = jiffies + (HZ * IP_CONFIG_TOV);
3853 do {
3854 for (idx = 0; idx < IP_ADDR_COUNT; idx++) {
3855 if (ip_idx[idx] == -1)
3856 continue;
3857
3858 ret = qla4xxx_get_ip_state(ha, 0, ip_idx[idx], sts);
3859
3860 if (ret == QLA_ERROR) {
3861 ip_idx[idx] = -1;
3862 continue;
3863 }
3864
3865 ip_state = (sts[1] & IP_STATE_MASK) >> IP_STATE_SHIFT;
3866
3867 DEBUG2(ql4_printk(KERN_INFO, ha,
3868 "Waiting for IP state for idx = %d, state = 0x%x\n",
3869 ip_idx[idx], ip_state));
3870 if (ip_state == IP_ADDRSTATE_UNCONFIGURED ||
3871 ip_state == IP_ADDRSTATE_INVALID ||
3872 ip_state == IP_ADDRSTATE_PREFERRED ||
3873 ip_state == IP_ADDRSTATE_DEPRICATED ||
3874 ip_state == IP_ADDRSTATE_DISABLING)
3875 ip_idx[idx] = -1;
3876
3877 }
3878
3879 /* Break if all IP states checked */
3880 if ((ip_idx[0] == -1) &&
3881 (ip_idx[1] == -1) &&
3882 (ip_idx[2] == -1) &&
3883 (ip_idx[3] == -1))
3884 break;
3885 schedule_timeout_uninterruptible(HZ);
3886 } while (time_after(wtime, jiffies));
3887}
3888
3889void qla4xxx_build_ddb_list(struct scsi_qla_host *ha, int is_reset)
3890{
3891 int max_ddbs;
3892 int ret;
3893 uint32_t idx = 0, next_idx = 0;
3894 uint32_t state = 0, conn_err = 0;
3895 uint16_t conn_id;
3896 struct dev_db_entry *fw_ddb_entry;
3897 struct ddb_entry *ddb_entry = NULL;
3898 dma_addr_t fw_ddb_dma;
3899 struct iscsi_cls_session *cls_sess;
3900 struct iscsi_session *sess;
3901 struct iscsi_cls_conn *cls_conn;
3902 struct iscsi_endpoint *ep;
3903 uint16_t cmds_max = 32, tmo = 0;
3904 uint32_t initial_cmdsn = 0;
3905 struct list_head list_st, list_nt; /* List of sendtargets */
3906 struct qla_ddb_index *st_ddb_idx, *st_ddb_idx_tmp;
3907 int fw_idx_size;
3908 unsigned long wtime;
3909 struct qla_ddb_index *nt_ddb_idx;
3910
3911 if (!test_bit(AF_LINK_UP, &ha->flags)) {
3912 set_bit(AF_BUILD_DDB_LIST, &ha->flags);
3913 ha->is_reset = is_reset;
3914 return;
3915 }
3916 max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
3917 MAX_DEV_DB_ENTRIES;
3918
3919 fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,
3920 &fw_ddb_dma);
3921 if (fw_ddb_entry == NULL) {
3922 DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n"));
3923 goto exit_ddb_list;
3924 }
3925
3926 INIT_LIST_HEAD(&list_st);
3927 INIT_LIST_HEAD(&list_nt);
3928 fw_idx_size = sizeof(struct qla_ddb_index);
3929
3930 for (idx = 0; idx < max_ddbs; idx = next_idx) {
3931 ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry,
3932 fw_ddb_dma, NULL,
3933 &next_idx, &state, &conn_err,
3934 NULL, &conn_id);
3935 if (ret == QLA_ERROR)
3936 break;
3937
3938 if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS)
3939 goto continue_next_st;
3940
3941 /* Check if ST, add to the list_st */
3942 if (strlen((char *) fw_ddb_entry->iscsi_name) != 0)
3943 goto continue_next_st;
3944
3945 st_ddb_idx = vzalloc(fw_idx_size);
3946 if (!st_ddb_idx)
3947 break;
3948
3949 st_ddb_idx->fw_ddb_idx = idx;
3950
3951 list_add_tail(&st_ddb_idx->list, &list_st);
3952continue_next_st:
3953 if (next_idx == 0)
3954 break;
3955 }
3956
3957 /* Before issuing conn open mbox, ensure all IPs states are configured
3958 * Note, conn open fails if IPs are not configured
3959 */
3960 qla4xxx_wait_for_ip_configuration(ha);
3961
3962 /* Go thru the STs and fire the sendtargets by issuing conn open mbx */
3963 list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) {
3964 qla4xxx_conn_open(ha, st_ddb_idx->fw_ddb_idx);
3965 }
3966
3967 /* Wait to ensure all sendtargets are done for min 12 sec wait */
3968 tmo = ((ha->def_timeout < LOGIN_TOV) ? LOGIN_TOV : ha->def_timeout);
3969 DEBUG2(ql4_printk(KERN_INFO, ha,
3970 "Default time to wait for build ddb %d\n", tmo));
3971
3972 wtime = jiffies + (HZ * tmo);
3973 do {
3974 list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st,
3975 list) {
3976 ret = qla4xxx_get_fwddb_entry(ha,
3977 st_ddb_idx->fw_ddb_idx,
3978 NULL, 0, NULL, &next_idx,
3979 &state, &conn_err, NULL,
3980 NULL);
3981 if (ret == QLA_ERROR)
3982 continue;
3983
3984 if (state == DDB_DS_NO_CONNECTION_ACTIVE ||
3985 state == DDB_DS_SESSION_FAILED) {
3986 list_del_init(&st_ddb_idx->list);
3987 vfree(st_ddb_idx);
3988 }
3989 }
3990 schedule_timeout_uninterruptible(HZ / 10);
3991 } while (time_after(wtime, jiffies));
3992
3993 /* Free up the sendtargets list */
3994 list_for_each_entry_safe(st_ddb_idx, st_ddb_idx_tmp, &list_st, list) {
3995 list_del_init(&st_ddb_idx->list);
3996 vfree(st_ddb_idx);
3997 }
3998
3999 for (idx = 0; idx < max_ddbs; idx = next_idx) {
4000 ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry,
4001 fw_ddb_dma, NULL,
4002 &next_idx, &state, &conn_err,
4003 NULL, &conn_id);
4004 if (ret == QLA_ERROR)
4005 break;
4006
4007 if (qla4xxx_verify_boot_idx(ha, idx) != QLA_SUCCESS)
4008 goto continue_next_nt;
4009
4010 /* Check if NT, then add to list it */
4011 if (strlen((char *) fw_ddb_entry->iscsi_name) == 0)
4012 goto continue_next_nt;
4013
4014 if (state == DDB_DS_NO_CONNECTION_ACTIVE ||
4015 state == DDB_DS_SESSION_FAILED) {
4016 DEBUG2(ql4_printk(KERN_INFO, ha,
4017 "Adding DDB to session = 0x%x\n",
4018 idx));
4019 if (is_reset == INIT_ADAPTER) {
4020 nt_ddb_idx = vmalloc(fw_idx_size);
4021 if (!nt_ddb_idx)
4022 break;
4023
4024 nt_ddb_idx->fw_ddb_idx = idx;
4025
4026 memcpy(&nt_ddb_idx->fw_ddb, fw_ddb_entry,
4027 sizeof(struct dev_db_entry));
4028
4029 if (qla4xxx_is_flash_ddb_exists(ha, &list_nt,
4030 fw_ddb_entry) == QLA_SUCCESS) {
4031 vfree(nt_ddb_idx);
4032 goto continue_next_nt;
4033 }
4034 list_add_tail(&nt_ddb_idx->list, &list_nt);
4035 } else if (is_reset == RESET_ADAPTER) {
4036 if (qla4xxx_is_session_exists(ha,
4037 fw_ddb_entry) == QLA_SUCCESS)
4038 goto continue_next_nt;
4039 }
4040
4041 /* Create session object, with INVALID_ENTRY,
4042 * the targer_id would get set when we issue the login
4043 */
4044 cls_sess = iscsi_session_setup(&qla4xxx_iscsi_transport,
4045 ha->host, cmds_max,
4046 sizeof(struct ddb_entry),
4047 sizeof(struct ql4_task_data),
4048 initial_cmdsn, INVALID_ENTRY);
4049 if (!cls_sess)
4050 goto exit_ddb_list;
4051
4052 /*
4053 * iscsi_session_setup increments the driver reference
4054 * count which wouldn't let the driver to be unloaded.
4055 * so calling module_put function to decrement the
4056 * reference count.
4057 **/
4058 module_put(qla4xxx_iscsi_transport.owner);
4059 sess = cls_sess->dd_data;
4060 ddb_entry = sess->dd_data;
4061 ddb_entry->sess = cls_sess;
4062
4063 cls_sess->recovery_tmo = ql4xsess_recovery_tmo;
4064 memcpy(&ddb_entry->fw_ddb_entry, fw_ddb_entry,
4065 sizeof(struct dev_db_entry));
4066
4067 qla4xxx_setup_flash_ddb_entry(ha, ddb_entry);
4068
4069 cls_conn = iscsi_conn_setup(cls_sess,
4070 sizeof(struct qla_conn),
4071 conn_id);
4072 if (!cls_conn)
4073 goto exit_ddb_list;
4074
4075 ddb_entry->conn = cls_conn;
4076
4077 /* Setup ep, for displaying attributes in sysfs */
4078 ep = qla4xxx_get_ep_fwdb(ha, fw_ddb_entry);
4079 if (ep) {
4080 ep->conn = cls_conn;
4081 cls_conn->ep = ep;
4082 } else {
4083 DEBUG2(ql4_printk(KERN_ERR, ha,
4084 "Unable to get ep\n"));
4085 }
4086
4087 /* Update sess/conn params */
4088 qla4xxx_copy_fwddb_param(ha, fw_ddb_entry, cls_sess,
4089 cls_conn);
4090
4091 if (is_reset == RESET_ADAPTER) {
4092 iscsi_block_session(cls_sess);
4093 /* Use the relogin path to discover new devices
4094 * by short-circuting the logic of setting
4095 * timer to relogin - instead set the flags
4096 * to initiate login right away.
4097 */
4098 set_bit(DPC_RELOGIN_DEVICE, &ha->dpc_flags);
4099 set_bit(DF_RELOGIN, &ddb_entry->flags);
4100 }
4101 }
4102continue_next_nt:
4103 if (next_idx == 0)
4104 break;
4105 }
4106exit_ddb_list:
4107 qla4xxx_free_nt_list(&list_nt);
4108 if (fw_ddb_entry)
4109 dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);
4110
4111 qla4xxx_free_ddb_index(ha);
4112}
4113
4114
3180/** 4115/**
3181 * qla4xxx_probe_adapter - callback function to probe HBA 4116 * qla4xxx_probe_adapter - callback function to probe HBA
3182 * @pdev: pointer to pci_dev structure 4117 * @pdev: pointer to pci_dev structure
@@ -3298,7 +4233,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
3298 * firmware 4233 * firmware
3299 * NOTE: interrupts enabled upon successful completion 4234 * NOTE: interrupts enabled upon successful completion
3300 */ 4235 */
3301 status = qla4xxx_initialize_adapter(ha); 4236 status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER);
3302 while ((!test_bit(AF_ONLINE, &ha->flags)) && 4237 while ((!test_bit(AF_ONLINE, &ha->flags)) &&
3303 init_retry_count++ < MAX_INIT_RETRIES) { 4238 init_retry_count++ < MAX_INIT_RETRIES) {
3304 4239
@@ -3319,7 +4254,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
3319 if (ha->isp_ops->reset_chip(ha) == QLA_ERROR) 4254 if (ha->isp_ops->reset_chip(ha) == QLA_ERROR)
3320 continue; 4255 continue;
3321 4256
3322 status = qla4xxx_initialize_adapter(ha); 4257 status = qla4xxx_initialize_adapter(ha, INIT_ADAPTER);
3323 } 4258 }
3324 4259
3325 if (!test_bit(AF_ONLINE, &ha->flags)) { 4260 if (!test_bit(AF_ONLINE, &ha->flags)) {
@@ -3386,12 +4321,16 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
3386 ha->host_no, ha->firmware_version[0], ha->firmware_version[1], 4321 ha->host_no, ha->firmware_version[0], ha->firmware_version[1],
3387 ha->patch_number, ha->build_number); 4322 ha->patch_number, ha->build_number);
3388 4323
3389 qla4xxx_create_chap_list(ha);
3390
3391 if (qla4xxx_setup_boot_info(ha)) 4324 if (qla4xxx_setup_boot_info(ha))
3392 ql4_printk(KERN_ERR, ha, "%s:ISCSI boot info setup failed\n", 4325 ql4_printk(KERN_ERR, ha, "%s:ISCSI boot info setup failed\n",
3393 __func__); 4326 __func__);
3394 4327
4328 /* Perform the build ddb list and login to each */
4329 qla4xxx_build_ddb_list(ha, INIT_ADAPTER);
4330 iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb);
4331
4332 qla4xxx_create_chap_list(ha);
4333
3395 qla4xxx_create_ifaces(ha); 4334 qla4xxx_create_ifaces(ha);
3396 return 0; 4335 return 0;
3397 4336
@@ -3449,6 +4388,38 @@ static void qla4xxx_prevent_other_port_reinit(struct scsi_qla_host *ha)
3449 } 4388 }
3450} 4389}
3451 4390
4391static void qla4xxx_destroy_fw_ddb_session(struct scsi_qla_host *ha)
4392{
4393 struct ddb_entry *ddb_entry;
4394 int options;
4395 int idx;
4396
4397 for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) {
4398
4399 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);
4400 if ((ddb_entry != NULL) &&
4401 (ddb_entry->ddb_type == FLASH_DDB)) {
4402
4403 options = LOGOUT_OPTION_CLOSE_SESSION;
4404 if (qla4xxx_session_logout_ddb(ha, ddb_entry, options)
4405 == QLA_ERROR)
4406 ql4_printk(KERN_ERR, ha, "%s: Logout failed\n",
4407 __func__);
4408
4409 qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);
4410 /*
4411 * we have decremented the reference count of the driver
4412 * when we setup the session to have the driver unload
4413 * to be seamless without actually destroying the
4414 * session
4415 **/
4416 try_module_get(qla4xxx_iscsi_transport.owner);
4417 iscsi_destroy_endpoint(ddb_entry->conn->ep);
4418 qla4xxx_free_ddb(ha, ddb_entry);
4419 iscsi_session_teardown(ddb_entry->sess);
4420 }
4421 }
4422}
3452/** 4423/**
3453 * qla4xxx_remove_adapter - calback function to remove adapter. 4424 * qla4xxx_remove_adapter - calback function to remove adapter.
3454 * @pci_dev: PCI device pointer 4425 * @pci_dev: PCI device pointer
@@ -3465,9 +4436,11 @@ static void __devexit qla4xxx_remove_adapter(struct pci_dev *pdev)
3465 /* destroy iface from sysfs */ 4436 /* destroy iface from sysfs */
3466 qla4xxx_destroy_ifaces(ha); 4437 qla4xxx_destroy_ifaces(ha);
3467 4438
3468 if (ha->boot_kset) 4439 if ((!ql4xdisablesysfsboot) && ha->boot_kset)
3469 iscsi_boot_destroy_kset(ha->boot_kset); 4440 iscsi_boot_destroy_kset(ha->boot_kset);
3470 4441
4442 qla4xxx_destroy_fw_ddb_session(ha);
4443
3471 scsi_remove_host(ha->host); 4444 scsi_remove_host(ha->host);
3472 4445
3473 qla4xxx_free_adapter(ha); 4446 qla4xxx_free_adapter(ha);
@@ -4115,7 +5088,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
4115 5088
4116 qla4_8xxx_idc_unlock(ha); 5089 qla4_8xxx_idc_unlock(ha);
4117 clear_bit(AF_FW_RECOVERY, &ha->flags); 5090 clear_bit(AF_FW_RECOVERY, &ha->flags);
4118 rval = qla4xxx_initialize_adapter(ha); 5091 rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
4119 qla4_8xxx_idc_lock(ha); 5092 qla4_8xxx_idc_lock(ha);
4120 5093
4121 if (rval != QLA_SUCCESS) { 5094 if (rval != QLA_SUCCESS) {
@@ -4151,7 +5124,7 @@ static uint32_t qla4_8xxx_error_recovery(struct scsi_qla_host *ha)
4151 if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) == 5124 if ((qla4_8xxx_rd_32(ha, QLA82XX_CRB_DEV_STATE) ==
4152 QLA82XX_DEV_READY)) { 5125 QLA82XX_DEV_READY)) {
4153 clear_bit(AF_FW_RECOVERY, &ha->flags); 5126 clear_bit(AF_FW_RECOVERY, &ha->flags);
4154 rval = qla4xxx_initialize_adapter(ha); 5127 rval = qla4xxx_initialize_adapter(ha, RESET_ADAPTER);
4155 if (rval == QLA_SUCCESS) { 5128 if (rval == QLA_SUCCESS) {
4156 ret = qla4xxx_request_irqs(ha); 5129 ret = qla4xxx_request_irqs(ha);
4157 if (ret) { 5130 if (ret) {
diff --git a/drivers/scsi/qla4xxx/ql4_version.h b/drivers/scsi/qla4xxx/ql4_version.h
index c15347d3f53..5254e57968f 100644
--- a/drivers/scsi/qla4xxx/ql4_version.h
+++ b/drivers/scsi/qla4xxx/ql4_version.h
@@ -5,4 +5,4 @@
5 * See LICENSE.qla4xxx for copyright and licensing details. 5 * See LICENSE.qla4xxx for copyright and licensing details.
6 */ 6 */
7 7
8#define QLA4XXX_DRIVER_VERSION "5.02.00-k8" 8#define QLA4XXX_DRIVER_VERSION "5.02.00-k9"