aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/bfa/bfad.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-04-07 02:53:30 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-07 02:53:30 -0400
commit4a35ecf8bf1c4b039503fa554100fe85c761de76 (patch)
tree9b75f5d5636004d9a9aa496924377379be09aa1f /drivers/scsi/bfa/bfad.c
parentb4d562e3c3553ac58c7120555c4e4aefbb090a2a (diff)
parentfb9e2d887243499b8d28efcf80821c4f6a092395 (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/bonding/bond_main.c drivers/net/via-velocity.c drivers/net/wireless/iwlwifi/iwl-agn.c
Diffstat (limited to 'drivers/scsi/bfa/bfad.c')
-rw-r--r--drivers/scsi/bfa/bfad.c208
1 files changed, 156 insertions, 52 deletions
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c
index b52b773d49d9..6bff08ea4029 100644
--- a/drivers/scsi/bfa/bfad.c
+++ b/drivers/scsi/bfa/bfad.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/kthread.h>
23#include "bfad_drv.h" 24#include "bfad_drv.h"
24#include "bfad_im.h" 25#include "bfad_im.h"
25#include "bfad_tm.h" 26#include "bfad_tm.h"
@@ -53,6 +54,7 @@ static int log_level = BFA_LOG_WARNING;
53static int ioc_auto_recover = BFA_TRUE; 54static int ioc_auto_recover = BFA_TRUE;
54static int ipfc_enable = BFA_FALSE; 55static int ipfc_enable = BFA_FALSE;
55static int ipfc_mtu = -1; 56static int ipfc_mtu = -1;
57static int fdmi_enable = BFA_TRUE;
56int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH; 58int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH;
57int bfa_linkup_delay = -1; 59int bfa_linkup_delay = -1;
58 60
@@ -74,6 +76,7 @@ module_param(log_level, int, S_IRUGO | S_IWUSR);
74module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); 76module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR);
75module_param(ipfc_enable, int, S_IRUGO | S_IWUSR); 77module_param(ipfc_enable, int, S_IRUGO | S_IWUSR);
76module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR); 78module_param(ipfc_mtu, int, S_IRUGO | S_IWUSR);
79module_param(fdmi_enable, int, S_IRUGO | S_IWUSR);
77module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR); 80module_param(bfa_linkup_delay, int, S_IRUGO | S_IWUSR);
78 81
79/* 82/*
@@ -95,6 +98,8 @@ bfad_fc4_probe(struct bfad_s *bfad)
95 98
96 if (ipfc_enable) 99 if (ipfc_enable)
97 bfad_ipfc_probe(bfad); 100 bfad_ipfc_probe(bfad);
101
102 bfad->bfad_flags |= BFAD_FC4_PROBE_DONE;
98ext: 103ext:
99 return rc; 104 return rc;
100} 105}
@@ -106,6 +111,7 @@ bfad_fc4_probe_undo(struct bfad_s *bfad)
106 bfad_tm_probe_undo(bfad); 111 bfad_tm_probe_undo(bfad);
107 if (ipfc_enable) 112 if (ipfc_enable)
108 bfad_ipfc_probe_undo(bfad); 113 bfad_ipfc_probe_undo(bfad);
114 bfad->bfad_flags &= ~BFAD_FC4_PROBE_DONE;
109} 115}
110 116
111static void 117static void
@@ -173,9 +179,19 @@ bfa_cb_init(void *drv, bfa_status_t init_status)
173{ 179{
174 struct bfad_s *bfad = drv; 180 struct bfad_s *bfad = drv;
175 181
176 if (init_status == BFA_STATUS_OK) 182 if (init_status == BFA_STATUS_OK) {
177 bfad->bfad_flags |= BFAD_HAL_INIT_DONE; 183 bfad->bfad_flags |= BFAD_HAL_INIT_DONE;
178 184
185 /* If BFAD_HAL_INIT_FAIL flag is set:
186 * Wake up the kernel thread to start
187 * the bfad operations after HAL init done
188 */
189 if ((bfad->bfad_flags & BFAD_HAL_INIT_FAIL)) {
190 bfad->bfad_flags &= ~BFAD_HAL_INIT_FAIL;
191 wake_up_process(bfad->bfad_tsk);
192 }
193 }
194
179 complete(&bfad->comp); 195 complete(&bfad->comp);
180} 196}
181 197
@@ -648,7 +664,7 @@ bfad_fcs_port_cfg(struct bfad_s *bfad)
648 664
649 sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no); 665 sprintf(symname, "%s-%d", BFAD_DRIVER_NAME, bfad->inst_no);
650 memcpy(port_cfg.sym_name.symname, symname, strlen(symname)); 666 memcpy(port_cfg.sym_name.symname, symname, strlen(symname));
651 bfa_pport_get_attr(&bfad->bfa, &attr); 667 bfa_fcport_get_attr(&bfad->bfa, &attr);
652 port_cfg.nwwn = attr.nwwn; 668 port_cfg.nwwn = attr.nwwn;
653 port_cfg.pwwn = attr.pwwn; 669 port_cfg.pwwn = attr.pwwn;
654 670
@@ -661,7 +677,6 @@ bfad_drv_init(struct bfad_s *bfad)
661 bfa_status_t rc; 677 bfa_status_t rc;
662 unsigned long flags; 678 unsigned long flags;
663 struct bfa_fcs_driver_info_s driver_info; 679 struct bfa_fcs_driver_info_s driver_info;
664 int i;
665 680
666 bfad->cfg_data.rport_del_timeout = rport_del_timeout; 681 bfad->cfg_data.rport_del_timeout = rport_del_timeout;
667 bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth; 682 bfad->cfg_data.lun_queue_depth = bfa_lun_queue_depth;
@@ -681,12 +696,7 @@ bfad_drv_init(struct bfad_s *bfad)
681 bfa_init_log(&bfad->bfa, bfad->logmod); 696 bfa_init_log(&bfad->bfa, bfad->logmod);
682 bfa_init_trc(&bfad->bfa, bfad->trcmod); 697 bfa_init_trc(&bfad->bfa, bfad->trcmod);
683 bfa_init_aen(&bfad->bfa, bfad->aen); 698 bfa_init_aen(&bfad->bfa, bfad->aen);
684 INIT_LIST_HEAD(&bfad->file_q); 699 memset(bfad->file_map, 0, sizeof(bfad->file_map));
685 INIT_LIST_HEAD(&bfad->file_free_q);
686 for (i = 0; i < BFAD_AEN_MAX_APPS; i++) {
687 bfa_q_qe_init(&bfad->file_buf[i].qe);
688 list_add_tail(&bfad->file_buf[i].qe, &bfad->file_free_q);
689 }
690 bfa_init_plog(&bfad->bfa, &bfad->plog_buf); 700 bfa_init_plog(&bfad->bfa, &bfad->plog_buf);
691 bfa_plog_init(&bfad->plog_buf); 701 bfa_plog_init(&bfad->plog_buf);
692 bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START, 702 bfa_plog_str(&bfad->plog_buf, BFA_PL_MID_DRVR, BFA_PL_EID_DRIVER_START,
@@ -746,8 +756,16 @@ bfad_drv_init(struct bfad_s *bfad)
746 bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod); 756 bfa_fcs_log_init(&bfad->bfa_fcs, bfad->logmod);
747 bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod); 757 bfa_fcs_trc_init(&bfad->bfa_fcs, bfad->trcmod);
748 bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen); 758 bfa_fcs_aen_init(&bfad->bfa_fcs, bfad->aen);
749 bfa_fcs_init(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE); 759 bfa_fcs_attach(&bfad->bfa_fcs, &bfad->bfa, bfad, BFA_FALSE);
760
761 /* Do FCS init only when HAL init is done */
762 if ((bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
763 bfa_fcs_init(&bfad->bfa_fcs);
764 bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
765 }
766
750 bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info); 767 bfa_fcs_driver_info_init(&bfad->bfa_fcs, &driver_info);
768 bfa_fcs_set_fdmi_param(&bfad->bfa_fcs, fdmi_enable);
751 spin_unlock_irqrestore(&bfad->bfad_lock, flags); 769 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
752 770
753 bfad->bfad_flags |= BFAD_DRV_INIT_DONE; 771 bfad->bfad_flags |= BFAD_DRV_INIT_DONE;
@@ -763,12 +781,21 @@ out_hal_mem_alloc_failure:
763void 781void
764bfad_drv_uninit(struct bfad_s *bfad) 782bfad_drv_uninit(struct bfad_s *bfad)
765{ 783{
784 unsigned long flags;
785
786 spin_lock_irqsave(&bfad->bfad_lock, flags);
787 init_completion(&bfad->comp);
788 bfa_stop(&bfad->bfa);
789 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
790 wait_for_completion(&bfad->comp);
791
766 del_timer_sync(&bfad->hal_tmo); 792 del_timer_sync(&bfad->hal_tmo);
767 bfa_isr_disable(&bfad->bfa); 793 bfa_isr_disable(&bfad->bfa);
768 bfa_detach(&bfad->bfa); 794 bfa_detach(&bfad->bfa);
769 bfad_remove_intr(bfad); 795 bfad_remove_intr(bfad);
770 bfa_assert(list_empty(&bfad->file_q));
771 bfad_hal_mem_release(bfad); 796 bfad_hal_mem_release(bfad);
797
798 bfad->bfad_flags &= ~BFAD_DRV_INIT_DONE;
772} 799}
773 800
774void 801void
@@ -859,6 +886,86 @@ bfad_drv_log_level_set(struct bfad_s *bfad)
859 bfa_log_set_level_all(&bfad->log_data, log_level); 886 bfa_log_set_level_all(&bfad->log_data, log_level);
860} 887}
861 888
889bfa_status_t
890bfad_start_ops(struct bfad_s *bfad)
891{
892 int retval;
893
894 /* PPORT FCS config */
895 bfad_fcs_port_cfg(bfad);
896
897 retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
898 if (retval != BFA_STATUS_OK)
899 goto out_cfg_pport_failure;
900
901 /* BFAD level FC4 (IM/TM/IPFC) specific resource allocation */
902 retval = bfad_fc4_probe(bfad);
903 if (retval != BFA_STATUS_OK) {
904 printk(KERN_WARNING "bfad_fc4_probe failed\n");
905 goto out_fc4_probe_failure;
906 }
907
908 bfad_drv_start(bfad);
909
910 /*
911 * If bfa_linkup_delay is set to -1 default; try to retrive the
912 * value using the bfad_os_get_linkup_delay(); else use the
913 * passed in module param value as the bfa_linkup_delay.
914 */
915 if (bfa_linkup_delay < 0) {
916
917 bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
918 bfad_os_rport_online_wait(bfad);
919 bfa_linkup_delay = -1;
920
921 } else {
922 bfad_os_rport_online_wait(bfad);
923 }
924
925 bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
926
927 return BFA_STATUS_OK;
928
929out_fc4_probe_failure:
930 bfad_fc4_probe_undo(bfad);
931 bfad_uncfg_pport(bfad);
932out_cfg_pport_failure:
933 return BFA_STATUS_FAILED;
934}
935
936int
937bfad_worker (void *ptr)
938{
939 struct bfad_s *bfad;
940 unsigned long flags;
941
942 bfad = (struct bfad_s *)ptr;
943
944 while (!kthread_should_stop()) {
945
946 /* Check if the FCS init is done from bfad_drv_init;
947 * if not done do FCS init and set the flag.
948 */
949 if (!(bfad->bfad_flags & BFAD_FCS_INIT_DONE)) {
950 spin_lock_irqsave(&bfad->bfad_lock, flags);
951 bfa_fcs_init(&bfad->bfa_fcs);
952 bfad->bfad_flags |= BFAD_FCS_INIT_DONE;
953 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
954 }
955
956 /* Start the bfad operations after HAL init done */
957 bfad_start_ops(bfad);
958
959 spin_lock_irqsave(&bfad->bfad_lock, flags);
960 bfad->bfad_tsk = NULL;
961 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
962
963 break;
964 }
965
966 return 0;
967}
968
862 /* 969 /*
863 * PCI_entry PCI driver entries * { 970 * PCI_entry PCI driver entries * {
864 */ 971 */
@@ -871,7 +978,6 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
871{ 978{
872 struct bfad_s *bfad; 979 struct bfad_s *bfad;
873 int error = -ENODEV, retval; 980 int error = -ENODEV, retval;
874 char buf[16];
875 981
876 /* 982 /*
877 * For single port cards - only claim function 0 983 * For single port cards - only claim function 0
@@ -902,8 +1008,7 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
902 bfa_trc(bfad, bfad_inst); 1008 bfa_trc(bfad, bfad_inst);
903 1009
904 bfad->logmod = &bfad->log_data; 1010 bfad->logmod = &bfad->log_data;
905 sprintf(buf, "%d", bfad_inst); 1011 bfa_log_init(bfad->logmod, (char *)pci_name(pdev), bfa_os_printf);
906 bfa_log_init(bfad->logmod, buf, bfa_os_printf);
907 1012
908 bfad_drv_log_level_set(bfad); 1013 bfad_drv_log_level_set(bfad);
909 1014
@@ -933,57 +1038,39 @@ bfad_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pid)
933 bfad->ref_count = 0; 1038 bfad->ref_count = 0;
934 bfad->pport.bfad = bfad; 1039 bfad->pport.bfad = bfad;
935 1040
1041 bfad->bfad_tsk = kthread_create(bfad_worker, (void *) bfad, "%s",
1042 "bfad_worker");
1043 if (IS_ERR(bfad->bfad_tsk)) {
1044 printk(KERN_INFO "bfad[%d]: Kernel thread"
1045 " creation failed!\n",
1046 bfad->inst_no);
1047 goto out_kthread_create_failure;
1048 }
1049
936 retval = bfad_drv_init(bfad); 1050 retval = bfad_drv_init(bfad);
937 if (retval != BFA_STATUS_OK) 1051 if (retval != BFA_STATUS_OK)
938 goto out_drv_init_failure; 1052 goto out_drv_init_failure;
939 if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { 1053 if (!(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1054 bfad->bfad_flags |= BFAD_HAL_INIT_FAIL;
940 printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no); 1055 printk(KERN_WARNING "bfad%d: hal init failed\n", bfad->inst_no);
941 goto ok; 1056 goto ok;
942 } 1057 }
943 1058
944 /* 1059 retval = bfad_start_ops(bfad);
945 * PPORT FCS config
946 */
947 bfad_fcs_port_cfg(bfad);
948
949 retval = bfad_cfg_pport(bfad, BFA_PORT_ROLE_FCP_IM);
950 if (retval != BFA_STATUS_OK) 1060 if (retval != BFA_STATUS_OK)
951 goto out_cfg_pport_failure; 1061 goto out_start_ops_failure;
952
953 /*
954 * BFAD level FC4 (IM/TM/IPFC) specific resource allocation
955 */
956 retval = bfad_fc4_probe(bfad);
957 if (retval != BFA_STATUS_OK) {
958 printk(KERN_WARNING "bfad_fc4_probe failed\n");
959 goto out_fc4_probe_failure;
960 }
961 1062
962 bfad_drv_start(bfad); 1063 kthread_stop(bfad->bfad_tsk);
963 1064 bfad->bfad_tsk = NULL;
964 /*
965 * If bfa_linkup_delay is set to -1 default; try to retrive the
966 * value using the bfad_os_get_linkup_delay(); else use the
967 * passed in module param value as the bfa_linkup_delay.
968 */
969 if (bfa_linkup_delay < 0) {
970 bfa_linkup_delay = bfad_os_get_linkup_delay(bfad);
971 bfad_os_rport_online_wait(bfad);
972 bfa_linkup_delay = -1;
973 } else {
974 bfad_os_rport_online_wait(bfad);
975 }
976 1065
977 bfa_log(bfad->logmod, BFA_LOG_LINUX_DEVICE_CLAIMED, bfad->pci_name);
978ok: 1066ok:
979 return 0; 1067 return 0;
980 1068
981out_fc4_probe_failure: 1069out_start_ops_failure:
982 bfad_fc4_probe_undo(bfad);
983 bfad_uncfg_pport(bfad);
984out_cfg_pport_failure:
985 bfad_drv_uninit(bfad); 1070 bfad_drv_uninit(bfad);
986out_drv_init_failure: 1071out_drv_init_failure:
1072 kthread_stop(bfad->bfad_tsk);
1073out_kthread_create_failure:
987 mutex_lock(&bfad_mutex); 1074 mutex_lock(&bfad_mutex);
988 bfad_inst--; 1075 bfad_inst--;
989 list_del(&bfad->list_entry); 1076 list_del(&bfad->list_entry);
@@ -1008,6 +1095,11 @@ bfad_pci_remove(struct pci_dev *pdev)
1008 1095
1009 bfa_trc(bfad, bfad->inst_no); 1096 bfa_trc(bfad, bfad->inst_no);
1010 1097
1098 spin_lock_irqsave(&bfad->bfad_lock, flags);
1099 if (bfad->bfad_tsk != NULL)
1100 kthread_stop(bfad->bfad_tsk);
1101 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1102
1011 if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE) 1103 if ((bfad->bfad_flags & BFAD_DRV_INIT_DONE)
1012 && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) { 1104 && !(bfad->bfad_flags & BFAD_HAL_INIT_DONE)) {
1013 1105
@@ -1024,13 +1116,25 @@ bfad_pci_remove(struct pci_dev *pdev)
1024 goto remove_sysfs; 1116 goto remove_sysfs;
1025 } 1117 }
1026 1118
1027 if (bfad->bfad_flags & BFAD_HAL_START_DONE) 1119 if (bfad->bfad_flags & BFAD_HAL_START_DONE) {
1028 bfad_drv_stop(bfad); 1120 bfad_drv_stop(bfad);
1121 } else if (bfad->bfad_flags & BFAD_DRV_INIT_DONE) {
1122 /* Invoking bfa_stop() before bfa_detach
1123 * when HAL and DRV init are success
1124 * but HAL start did not occur.
1125 */
1126 spin_lock_irqsave(&bfad->bfad_lock, flags);
1127 init_completion(&bfad->comp);
1128 bfa_stop(&bfad->bfa);
1129 spin_unlock_irqrestore(&bfad->bfad_lock, flags);
1130 wait_for_completion(&bfad->comp);
1131 }
1029 1132
1030 bfad_remove_intr(bfad); 1133 bfad_remove_intr(bfad);
1031
1032 del_timer_sync(&bfad->hal_tmo); 1134 del_timer_sync(&bfad->hal_tmo);
1033 bfad_fc4_probe_undo(bfad); 1135
1136 if (bfad->bfad_flags & BFAD_FC4_PROBE_DONE)
1137 bfad_fc4_probe_undo(bfad);
1034 1138
1035 if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE) 1139 if (bfad->bfad_flags & BFAD_CFG_PPORT_DONE)
1036 bfad_uncfg_pport(bfad); 1140 bfad_uncfg_pport(bfad);