aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaren Higgins <karen.higgins@qlogic.com>2011-03-21 06:34:27 -0400
committerJames Bottomley <James.Bottomley@suse.de>2011-03-23 13:52:59 -0400
commit7edd9a7b28f57d8a5bcdb1a0def2aa09d1dd49d4 (patch)
tree86eba449ce85a666c4acb11981f0c960a4792e69
parentf9880e76fd15795b5917b20f54eeca764b0f3ccb (diff)
[SCSI] qla4xxx: cleanup DDB relogin logic during initialization
Driver has capability to add device dynamically and present them to OS, driver no longer need to wait for DDBs to come online during driver initialization. Driver still issues a relogin for DDBs that are not online, but no longer wait for DDB to come online. Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: Karen Higgins <karen.higgins@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h5
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h1
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c183
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c29
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c3
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c4
6 files changed, 33 insertions, 192 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 2fc0045b1a52..b46d0dc9a48e 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -233,9 +233,6 @@ struct ddb_entry {
233 233
234 unsigned long flags; /* DDB Flags */ 234 unsigned long flags; /* DDB Flags */
235 235
236 unsigned long dev_scan_wait_to_start_relogin;
237 unsigned long dev_scan_wait_to_complete_relogin;
238
239 uint16_t fw_ddb_index; /* DDB firmware index */ 236 uint16_t fw_ddb_index; /* DDB firmware index */
240 uint16_t options; 237 uint16_t options;
241 uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */ 238 uint32_t fw_ddb_device_state; /* F/W Device State -- see ql4_fw.h */
@@ -479,7 +476,6 @@ struct scsi_qla_host {
479 uint32_t timer_active; 476 uint32_t timer_active;
480 477
481 /* Recovery Timers */ 478 /* Recovery Timers */
482 uint32_t discovery_wait;
483 atomic_t check_relogin_timeouts; 479 atomic_t check_relogin_timeouts;
484 uint32_t retry_reset_ha_cnt; 480 uint32_t retry_reset_ha_cnt;
485 uint32_t isp_reset_timer; /* reset test timer */ 481 uint32_t isp_reset_timer; /* reset test timer */
@@ -765,6 +761,5 @@ static inline void ql4xxx_unlock_drvr(struct scsi_qla_host *a)
765/* Defines for process_aen() */ 761/* Defines for process_aen() */
766#define PROCESS_ALL_AENS 0 762#define PROCESS_ALL_AENS 0
767#define FLUSH_DDB_CHANGED_AENS 1 763#define FLUSH_DDB_CHANGED_AENS 1
768#define RELOGIN_DDB_CHANGED_AENS 2
769 764
770#endif /*_QLA4XXX_H */ 765#endif /*_QLA4XXX_H */
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 8fad99b7eef4..cc53e3fbd78c 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -136,7 +136,6 @@ void qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha);
136void qla4_8xxx_set_drv_active(struct scsi_qla_host *ha); 136void qla4_8xxx_set_drv_active(struct scsi_qla_host *ha);
137 137
138extern int ql4xextended_error_logging; 138extern int ql4xextended_error_logging;
139extern int ql4xdiscoverywait;
140extern int ql4xdontresethba; 139extern int ql4xdontresethba;
141extern int ql4xenablemsix; 140extern int ql4xenablemsix;
142 141
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index 22fc57e2bc05..bf1c30b17a82 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -723,13 +723,38 @@ int qla4_is_relogin_allowed(struct scsi_qla_host *ha, uint32_t conn_err)
723 return relogin; 723 return relogin;
724} 724}
725 725
726static void qla4xxx_flush_AENS(struct scsi_qla_host *ha)
727{
728 unsigned long wtime;
729
730 /* Flush the 0x8014 AEN from the firmware as a result of
731 * Auto connect. We are basically doing get_firmware_ddb()
732 * to determine whether we need to log back in or not.
733 * Trying to do a set ddb before we have processed 0x8014
734 * will result in another set_ddb() for the same ddb. In other
735 * words there will be stale entries in the aen_q.
736 */
737 wtime = jiffies + (2 * HZ);
738 do {
739 if (qla4xxx_get_firmware_state(ha) == QLA_SUCCESS)
740 if (ha->firmware_state & (BIT_2 | BIT_0))
741 return;
742
743 if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags))
744 qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
745
746 msleep(1000);
747 } while (!time_after_eq(jiffies, wtime));
748}
749
726/** 750/**
727 * qla4xxx_configure_ddbs - builds driver ddb list 751 * qla4xxx_build_ddb_list - builds driver ddb list
728 * @ha: Pointer to host adapter structure. 752 * @ha: Pointer to host adapter structure.
729 * 753 *
730 * This routine searches for all valid firmware ddb entries and builds 754 * This routine searches for all valid firmware ddb entries and builds
731 * an internal ddb list. Ddbs that are considered valid are those with 755 * an internal ddb list. Ddbs that are considered valid are those with
732 * a device state of SESSION_ACTIVE. 756 * a device state of SESSION_ACTIVE.
757 * A relogin (set_ddb) is issued for DDBs that are not online.
733 **/ 758 **/
734static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha) 759static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
735{ 760{
@@ -744,6 +769,8 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
744 uint32_t ipv6_device; 769 uint32_t ipv6_device;
745 uint32_t new_tgt; 770 uint32_t new_tgt;
746 771
772 qla4xxx_flush_AENS(ha);
773
747 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 774 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
748 &fw_ddb_entry_dma, GFP_KERNEL); 775 &fw_ddb_entry_dma, GFP_KERNEL);
749 if (fw_ddb_entry == NULL) { 776 if (fw_ddb_entry == NULL) {
@@ -847,144 +874,6 @@ exit_build_ddb_list_no_free:
847 return status; 874 return status;
848} 875}
849 876
850struct qla4_relog_scan {
851 int halt_wait;
852 uint32_t conn_err;
853 uint32_t fw_ddb_index;
854 uint32_t next_fw_ddb_index;
855 uint32_t fw_ddb_device_state;
856};
857
858static int qla4_test_rdy(struct scsi_qla_host *ha, struct qla4_relog_scan *rs)
859{
860 struct ddb_entry *ddb_entry;
861
862 if (qla4_is_relogin_allowed(ha, rs->conn_err)) {
863 /* We either have a device that is in
864 * the process of relogging in or a
865 * device that is waiting to be
866 * relogged in */
867 rs->halt_wait = 0;
868
869 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha,
870 rs->fw_ddb_index);
871 if (ddb_entry == NULL)
872 return QLA_ERROR;
873
874 if (ddb_entry->dev_scan_wait_to_start_relogin != 0
875 && time_after_eq(jiffies,
876 ddb_entry->
877 dev_scan_wait_to_start_relogin))
878 {
879 ddb_entry->dev_scan_wait_to_start_relogin = 0;
880 qla4xxx_set_ddb_entry(ha, rs->fw_ddb_index, 0);
881 }
882 }
883 return QLA_SUCCESS;
884}
885
886static int qla4_scan_for_relogin(struct scsi_qla_host *ha,
887 struct qla4_relog_scan *rs)
888{
889 int error;
890
891 /* scan for relogins
892 * ----------------- */
893 for (rs->fw_ddb_index = 0; rs->fw_ddb_index < MAX_DDB_ENTRIES;
894 rs->fw_ddb_index = rs->next_fw_ddb_index) {
895 if (qla4xxx_get_fwddb_entry(ha, rs->fw_ddb_index, NULL, 0,
896 NULL, &rs->next_fw_ddb_index,
897 &rs->fw_ddb_device_state,
898 &rs->conn_err, NULL, NULL)
899 == QLA_ERROR)
900 return QLA_ERROR;
901
902 if (rs->fw_ddb_device_state == DDB_DS_LOGIN_IN_PROCESS)
903 rs->halt_wait = 0;
904
905 if (rs->fw_ddb_device_state == DDB_DS_SESSION_FAILED ||
906 rs->fw_ddb_device_state == DDB_DS_NO_CONNECTION_ACTIVE) {
907 error = qla4_test_rdy(ha, rs);
908 if (error)
909 return error;
910 }
911
912 /* We know we've reached the last device when
913 * next_fw_ddb_index is 0 */
914 if (rs->next_fw_ddb_index == 0)
915 break;
916 }
917 return QLA_SUCCESS;
918}
919
920/**
921 * qla4xxx_devices_ready - wait for target devices to be logged in
922 * @ha: pointer to adapter structure
923 *
924 * This routine waits up to ql4xdiscoverywait seconds
925 * F/W database during driver load time.
926 **/
927static int qla4xxx_devices_ready(struct scsi_qla_host *ha)
928{
929 int error;
930 unsigned long discovery_wtime;
931 struct qla4_relog_scan rs;
932
933 discovery_wtime = jiffies + (ql4xdiscoverywait * HZ);
934
935 DEBUG(printk("Waiting (%d) for devices ...\n", ql4xdiscoverywait));
936 do {
937 /* poll for AEN. */
938 qla4xxx_get_firmware_state(ha);
939 if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags)) {
940 /* Set time-between-relogin timer */
941 qla4xxx_process_aen(ha, RELOGIN_DDB_CHANGED_AENS);
942 }
943
944 /* if no relogins active or needed, halt discvery wait */
945 rs.halt_wait = 1;
946
947 error = qla4_scan_for_relogin(ha, &rs);
948
949 if (rs.halt_wait) {
950 DEBUG2(printk("scsi%ld: %s: Delay halted. Devices "
951 "Ready.\n", ha->host_no, __func__));
952 return QLA_SUCCESS;
953 }
954
955 msleep(2000);
956 } while (!time_after_eq(jiffies, discovery_wtime));
957
958 DEBUG3(qla4xxx_get_conn_event_log(ha));
959
960 return QLA_SUCCESS;
961}
962
963static void qla4xxx_flush_AENS(struct scsi_qla_host *ha)
964{
965 unsigned long wtime;
966
967 /* Flush the 0x8014 AEN from the firmware as a result of
968 * Auto connect. We are basically doing get_firmware_ddb()
969 * to determine whether we need to log back in or not.
970 * Trying to do a set ddb before we have processed 0x8014
971 * will result in another set_ddb() for the same ddb. In other
972 * words there will be stale entries in the aen_q.
973 */
974 wtime = jiffies + (2 * HZ);
975 do {
976 if (qla4xxx_get_firmware_state(ha) == QLA_SUCCESS)
977 if (ha->firmware_state & (BIT_2 | BIT_0))
978 return;
979
980 if (test_and_clear_bit(DPC_AEN, &ha->dpc_flags))
981 qla4xxx_process_aen(ha, FLUSH_DDB_CHANGED_AENS);
982
983 msleep(1000);
984 } while (!time_after_eq(jiffies, wtime));
985
986}
987
988static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha) 877static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha)
989{ 878{
990 uint16_t fw_ddb_index; 879 uint16_t fw_ddb_index;
@@ -996,22 +885,12 @@ static int qla4xxx_initialize_ddb_list(struct scsi_qla_host *ha)
996 885
997 for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; fw_ddb_index++) 886 for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; fw_ddb_index++)
998 ha->fw_ddb_index_map[fw_ddb_index] = 887 ha->fw_ddb_index_map[fw_ddb_index] =
999 (struct ddb_entry *)INVALID_ENTRY; 888 (struct ddb_entry *)INVALID_ENTRY;
1000 889
1001 ha->tot_ddbs = 0; 890 ha->tot_ddbs = 0;
1002 891
1003 qla4xxx_flush_AENS(ha); 892 /* Perform device discovery and build ddb list. */
1004 893 status = qla4xxx_build_ddb_list(ha);
1005 /* Wait for an AEN */
1006 qla4xxx_devices_ready(ha);
1007
1008 /*
1009 * First perform device discovery for active
1010 * fw ddb indexes and build
1011 * ddb list.
1012 */
1013 if ((status = qla4xxx_build_ddb_list(ha)) == QLA_ERROR)
1014 return status;
1015 894
1016 return status; 895 return status;
1017} 896}
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 03e028e6e809..2ef1a986f5c0 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -1008,34 +1008,9 @@ void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen)
1008 mbox_sts[0], mbox_sts[2], 1008 mbox_sts[0], mbox_sts[2],
1009 mbox_sts[3])); 1009 mbox_sts[3]));
1010 break; 1010 break;
1011 } else if (process_aen == RELOGIN_DDB_CHANGED_AENS) {
1012 /* for use during init time, we only want to
1013 * relogin non-active ddbs */
1014 struct ddb_entry *ddb_entry;
1015
1016 ddb_entry =
1017 /* FIXME: name length? */
1018 qla4xxx_lookup_ddb_by_fw_index(ha,
1019 mbox_sts[2]);
1020 if (!ddb_entry)
1021 break;
1022
1023 ddb_entry->dev_scan_wait_to_complete_relogin =
1024 0;
1025 ddb_entry->dev_scan_wait_to_start_relogin =
1026 jiffies +
1027 ((ddb_entry->default_time2wait +
1028 4) * HZ);
1029
1030 DEBUG2(printk("scsi%ld: ddb [%d] initiate"
1031 " RELOGIN after %d seconds\n",
1032 ha->host_no,
1033 ddb_entry->fw_ddb_index,
1034 ddb_entry->default_time2wait +
1035 4));
1036 break;
1037 } 1011 }
1038 1012 case PROCESS_ALL_AENS:
1013 default:
1039 if (mbox_sts[1] == 0) { /* Global DB change. */ 1014 if (mbox_sts[1] == 0) { /* Global DB change. */
1040 qla4xxx_reinitialize_ddb_list(ha); 1015 qla4xxx_reinitialize_ddb_list(ha);
1041 } else if (mbox_sts[1] == 1) { /* Specific device. */ 1016 } else if (mbox_sts[1] == 1) { /* Specific device. */
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index 47b259190b5a..379df2bde9db 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -407,9 +407,6 @@ qla4xxx_update_local_ifcb(struct scsi_qla_host *ha,
407 /*memcpy(ha->alias, init_fw_cb->Alias, 407 /*memcpy(ha->alias, init_fw_cb->Alias,
408 min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/ 408 min(sizeof(ha->alias), sizeof(init_fw_cb->Alias)));*/
409 409
410 /* Save Command Line Paramater info */
411 ha->discovery_wait = ql4xdiscoverywait;
412
413 if (ha->acb_version == ACB_SUPPORTED) { 410 if (ha->acb_version == ACB_SUPPORTED) {
414 ha->ipv6_options = init_fw_cb->ipv6_opts; 411 ha->ipv6_options = init_fw_cb->ipv6_opts;
415 ha->ipv6_addl_options = init_fw_cb->ipv6_addtl_opts; 412 ha->ipv6_addl_options = init_fw_cb->ipv6_addtl_opts;
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 409b20d62ef5..1d5c6fbbfaae 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -29,10 +29,6 @@ static struct kmem_cache *srb_cachep;
29/* 29/*
30 * Module parameter information and variables 30 * Module parameter information and variables
31 */ 31 */
32int ql4xdiscoverywait = 60;
33module_param(ql4xdiscoverywait, int, S_IRUGO | S_IWUSR);
34MODULE_PARM_DESC(ql4xdiscoverywait, "Discovery wait time");
35
36int ql4xdontresethba = 0; 32int ql4xdontresethba = 0;
37module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR); 33module_param(ql4xdontresethba, int, S_IRUGO | S_IWUSR);
38MODULE_PARM_DESC(ql4xdontresethba, 34MODULE_PARM_DESC(ql4xdontresethba,