aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuinn Tran <quinn.tran@cavium.com>2017-03-15 12:48:54 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2017-03-18 20:28:37 -0400
commit482c9dc79204bb83c3433a59680c787a0b98c000 (patch)
tree45280a831e7e958679769b616244ced62fbfbccf
parentc423437e3ff41b8ca551ab6621baf11538dbfe9d (diff)
qla2xxx: Change scsi host lookup method.
For target mode, when new scsi command arrive, driver first performs a look up of the SCSI Host. The current look up method is based on the ALPA portion of the NPort ID. For Cisco switch, the ALPA can not be used as the index. Instead, the new search method is based on the full value of the Nport_ID via btree lib. Signed-off-by: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/scsi/qla2xxx/Kconfig1
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h2
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c14
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c28
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_target.c92
7 files changed, 100 insertions, 40 deletions
diff --git a/drivers/scsi/qla2xxx/Kconfig b/drivers/scsi/qla2xxx/Kconfig
index 67c0d5aa3212..de952935b5d2 100644
--- a/drivers/scsi/qla2xxx/Kconfig
+++ b/drivers/scsi/qla2xxx/Kconfig
@@ -3,6 +3,7 @@ config SCSI_QLA_FC
3 depends on PCI && SCSI 3 depends on PCI && SCSI
4 depends on SCSI_FC_ATTRS 4 depends on SCSI_FC_ATTRS
5 select FW_LOADER 5 select FW_LOADER
6 select BTREE
6 ---help--- 7 ---help---
7 This qla2xxx driver supports all QLogic Fibre Channel 8 This qla2xxx driver supports all QLogic Fibre Channel
8 PCI and PCIe host adapters. 9 PCI and PCIe host adapters.
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 089480280558..9251918773b1 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -25,6 +25,7 @@
25#include <linux/firmware.h> 25#include <linux/firmware.h>
26#include <linux/aer.h> 26#include <linux/aer.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/btree.h>
28 29
29#include <scsi/scsi.h> 30#include <scsi/scsi.h>
30#include <scsi/scsi_host.h> 31#include <scsi/scsi_host.h>
@@ -3311,6 +3312,7 @@ struct qlt_hw_data {
3311 spinlock_t sess_lock; 3312 spinlock_t sess_lock;
3312 int rspq_vector_cpuid; 3313 int rspq_vector_cpuid;
3313 spinlock_t atio_lock ____cacheline_aligned; 3314 spinlock_t atio_lock ____cacheline_aligned;
3315 struct btree_head32 host_map;
3314}; 3316};
3315 3317
3316#define MAX_QFULL_CMDS_ALLOC 8192 3318#define MAX_QFULL_CMDS_ALLOC 8192
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 323b912b47f7..5b2451745e9f 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -854,5 +854,7 @@ extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *,
854 uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **); 854 uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **);
855void qla24xx_delete_sess_fn(struct work_struct *); 855void qla24xx_delete_sess_fn(struct work_struct *);
856void qlt_unknown_atio_work_fn(struct work_struct *); 856void qlt_unknown_atio_work_fn(struct work_struct *);
857void qlt_update_host_map(struct scsi_qla_host *, port_id_t);
858void qlt_remove_target_resources(struct qla_hw_data *);
857 859
858#endif /* _QLA_GBL_H */ 860#endif /* _QLA_GBL_H */
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index b1bfa63f7d4e..b0f6ad3020d3 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -3340,8 +3340,8 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
3340 uint8_t domain; 3340 uint8_t domain;
3341 char connect_type[22]; 3341 char connect_type[22];
3342 struct qla_hw_data *ha = vha->hw; 3342 struct qla_hw_data *ha = vha->hw;
3343 unsigned long flags;
3344 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); 3343 scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
3344 port_id_t id;
3345 3345
3346 /* Get host addresses. */ 3346 /* Get host addresses. */
3347 rval = qla2x00_get_adapter_id(vha, 3347 rval = qla2x00_get_adapter_id(vha,
@@ -3419,13 +3419,11 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
3419 3419
3420 /* Save Host port and loop ID. */ 3420 /* Save Host port and loop ID. */
3421 /* byte order - Big Endian */ 3421 /* byte order - Big Endian */
3422 vha->d_id.b.domain = domain; 3422 id.b.domain = domain;
3423 vha->d_id.b.area = area; 3423 id.b.area = area;
3424 vha->d_id.b.al_pa = al_pa; 3424 id.b.al_pa = al_pa;
3425 3425 id.b.rsvd_1 = 0;
3426 spin_lock_irqsave(&ha->vport_slock, flags); 3426 qlt_update_host_map(vha, id);
3427 qlt_update_vp_map(vha, SET_AL_PA);
3428 spin_unlock_irqrestore(&ha->vport_slock, flags);
3429 3427
3430 if (!vha->flags.init_done) 3428 if (!vha->flags.init_done)
3431 ql_log(ql_log_info, vha, 0x2010, 3429 ql_log(ql_log_info, vha, 0x2010,
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index e40ed570d3c1..53d9579acc74 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3623,6 +3623,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
3623 scsi_qla_host_t *vp = NULL; 3623 scsi_qla_host_t *vp = NULL;
3624 unsigned long flags; 3624 unsigned long flags;
3625 int found; 3625 int found;
3626 port_id_t id;
3626 3627
3627 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6, 3628 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b6,
3628 "Entered %s.\n", __func__); 3629 "Entered %s.\n", __func__);
@@ -3630,6 +3631,11 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
3630 if (rptid_entry->entry_status != 0) 3631 if (rptid_entry->entry_status != 0)
3631 return; 3632 return;
3632 3633
3634 id.b.domain = rptid_entry->port_id[2];
3635 id.b.area = rptid_entry->port_id[1];
3636 id.b.al_pa = rptid_entry->port_id[0];
3637 id.b.rsvd_1 = 0;
3638
3633 if (rptid_entry->format == 0) { 3639 if (rptid_entry->format == 0) {
3634 /* loop */ 3640 /* loop */
3635 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7, 3641 ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x10b7,
@@ -3641,13 +3647,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
3641 rptid_entry->port_id[2], rptid_entry->port_id[1], 3647 rptid_entry->port_id[2], rptid_entry->port_id[1],
3642 rptid_entry->port_id[0]); 3648 rptid_entry->port_id[0]);
3643 3649
3644 vha->d_id.b.domain = rptid_entry->port_id[2]; 3650 qlt_update_host_map(vha, id);
3645 vha->d_id.b.area = rptid_entry->port_id[1];
3646 vha->d_id.b.al_pa = rptid_entry->port_id[0];
3647
3648 spin_lock_irqsave(&ha->vport_slock, flags);
3649 qlt_update_vp_map(vha, SET_AL_PA);
3650 spin_unlock_irqrestore(&ha->vport_slock, flags);
3651 3651
3652 } else if (rptid_entry->format == 1) { 3652 } else if (rptid_entry->format == 1) {
3653 /* fabric */ 3653 /* fabric */
@@ -3673,12 +3673,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
3673 WWN_SIZE); 3673 WWN_SIZE);
3674 } 3674 }
3675 3675
3676 vha->d_id.b.domain = rptid_entry->port_id[2]; 3676 qlt_update_host_map(vha, id);
3677 vha->d_id.b.area = rptid_entry->port_id[1];
3678 vha->d_id.b.al_pa = rptid_entry->port_id[0];
3679 spin_lock_irqsave(&ha->vport_slock, flags);
3680 qlt_update_vp_map(vha, SET_AL_PA);
3681 spin_unlock_irqrestore(&ha->vport_slock, flags);
3682 } 3677 }
3683 3678
3684 fc_host_port_name(vha->host) = 3679 fc_host_port_name(vha->host) =
@@ -3714,12 +3709,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
3714 if (!found) 3709 if (!found)
3715 return; 3710 return;
3716 3711
3717 vp->d_id.b.domain = rptid_entry->port_id[2]; 3712 qlt_update_host_map(vp, id);
3718 vp->d_id.b.area = rptid_entry->port_id[1];
3719 vp->d_id.b.al_pa = rptid_entry->port_id[0];
3720 spin_lock_irqsave(&ha->vport_slock, flags);
3721 qlt_update_vp_map(vp, SET_AL_PA);
3722 spin_unlock_irqrestore(&ha->vport_slock, flags);
3723 3713
3724 /* 3714 /*
3725 * Cannot configure here as we are still sitting on the 3715 * Cannot configure here as we are still sitting on the
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 54d4e802bde0..344faf59783d 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3469,6 +3469,7 @@ qla2x00_remove_one(struct pci_dev *pdev)
3469 qla2x00_free_sysfs_attr(base_vha, true); 3469 qla2x00_free_sysfs_attr(base_vha, true);
3470 3470
3471 fc_remove_host(base_vha->host); 3471 fc_remove_host(base_vha->host);
3472 qlt_remove_target_resources(ha);
3472 3473
3473 scsi_remove_host(base_vha->host); 3474 scsi_remove_host(base_vha->host);
3474 3475
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 38bdcd325fa4..7278e046bf87 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -187,21 +187,23 @@ static inline
187struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha, 187struct scsi_qla_host *qlt_find_host_by_d_id(struct scsi_qla_host *vha,
188 uint8_t *d_id) 188 uint8_t *d_id)
189{ 189{
190 struct qla_hw_data *ha = vha->hw; 190 struct scsi_qla_host *host;
191 uint8_t vp_idx; 191 uint32_t key = 0;
192
193 if ((vha->d_id.b.area != d_id[1]) || (vha->d_id.b.domain != d_id[0]))
194 return NULL;
195 192
196 if (vha->d_id.b.al_pa == d_id[2]) 193 if ((vha->d_id.b.area == d_id[1]) && (vha->d_id.b.domain == d_id[0]) &&
194 (vha->d_id.b.al_pa == d_id[2]))
197 return vha; 195 return vha;
198 196
199 BUG_ON(ha->tgt.tgt_vp_map == NULL); 197 key = (uint32_t)d_id[0] << 16;
200 vp_idx = ha->tgt.tgt_vp_map[d_id[2]].idx; 198 key |= (uint32_t)d_id[1] << 8;
201 if (likely(test_bit(vp_idx, ha->vp_idx_map))) 199 key |= (uint32_t)d_id[2];
202 return ha->tgt.tgt_vp_map[vp_idx].vha;
203 200
204 return NULL; 201 host = btree_lookup32(&vha->hw->tgt.host_map, key);
202 if (!host)
203 ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
204 "Unable to find host %06x\n", key);
205
206 return host;
205} 207}
206 208
207static inline 209static inline
@@ -6040,6 +6042,17 @@ int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha)
6040 return 0; 6042 return 0;
6041} 6043}
6042 6044
6045void qlt_remove_target_resources(struct qla_hw_data *ha)
6046{
6047 struct scsi_qla_host *node;
6048 u32 key = 0;
6049
6050 btree_for_each_safe32(&ha->tgt.host_map, key, node)
6051 btree_remove32(&ha->tgt.host_map, key);
6052
6053 btree_destroy32(&ha->tgt.host_map);
6054}
6055
6043static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, 6056static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn,
6044 unsigned char *b) 6057 unsigned char *b)
6045{ 6058{
@@ -6693,6 +6706,8 @@ qlt_modify_vp_config(struct scsi_qla_host *vha,
6693void 6706void
6694qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) 6707qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha)
6695{ 6708{
6709 int rc;
6710
6696 if (!QLA_TGT_MODE_ENABLED()) 6711 if (!QLA_TGT_MODE_ENABLED())
6697 return; 6712 return;
6698 6713
@@ -6712,6 +6727,13 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha)
6712 qlt_unknown_atio_work_fn); 6727 qlt_unknown_atio_work_fn);
6713 6728
6714 qlt_clear_mode(base_vha); 6729 qlt_clear_mode(base_vha);
6730
6731 rc = btree_init32(&ha->tgt.host_map);
6732 if (rc)
6733 ql_log(ql_log_info, base_vha, 0xffff,
6734 "Unable to initialize ha->host_map btree\n");
6735
6736 qlt_update_vp_map(base_vha, SET_VP_IDX);
6715} 6737}
6716 6738
6717irqreturn_t 6739irqreturn_t
@@ -6820,25 +6842,69 @@ qlt_mem_free(struct qla_hw_data *ha)
6820void 6842void
6821qlt_update_vp_map(struct scsi_qla_host *vha, int cmd) 6843qlt_update_vp_map(struct scsi_qla_host *vha, int cmd)
6822{ 6844{
6845 void *slot;
6846 u32 key;
6847 int rc;
6848
6823 if (!QLA_TGT_MODE_ENABLED()) 6849 if (!QLA_TGT_MODE_ENABLED())
6824 return; 6850 return;
6825 6851
6852 key = vha->d_id.b24;
6853
6826 switch (cmd) { 6854 switch (cmd) {
6827 case SET_VP_IDX: 6855 case SET_VP_IDX:
6828 vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha; 6856 vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha;
6829 break; 6857 break;
6830 case SET_AL_PA: 6858 case SET_AL_PA:
6831 vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = vha->vp_idx; 6859 slot = btree_lookup32(&vha->hw->tgt.host_map, key);
6860 if (!slot) {
6861 ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
6862 "Save vha in host_map %p %06x\n", vha, key);
6863 rc = btree_insert32(&vha->hw->tgt.host_map,
6864 key, vha, GFP_ATOMIC);
6865 if (rc)
6866 ql_log(ql_log_info, vha, 0xffff,
6867 "Unable to insert s_id into host_map: %06x\n",
6868 key);
6869 return;
6870 }
6871 ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
6872 "replace existing vha in host_map %p %06x\n", vha, key);
6873 btree_update32(&vha->hw->tgt.host_map, key, vha);
6832 break; 6874 break;
6833 case RESET_VP_IDX: 6875 case RESET_VP_IDX:
6834 vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL; 6876 vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL;
6835 break; 6877 break;
6836 case RESET_AL_PA: 6878 case RESET_AL_PA:
6837 vha->hw->tgt.tgt_vp_map[vha->d_id.b.al_pa].idx = 0; 6879 ql_dbg(ql_dbg_tgt_mgt, vha, 0xffff,
6880 "clear vha in host_map %p %06x\n", vha, key);
6881 slot = btree_lookup32(&vha->hw->tgt.host_map, key);
6882 if (slot)
6883 btree_remove32(&vha->hw->tgt.host_map, key);
6884 vha->d_id.b24 = 0;
6838 break; 6885 break;
6839 } 6886 }
6840} 6887}
6841 6888
6889void qlt_update_host_map(struct scsi_qla_host *vha, port_id_t id)
6890{
6891 unsigned long flags;
6892 struct qla_hw_data *ha = vha->hw;
6893
6894 if (!vha->d_id.b24) {
6895 spin_lock_irqsave(&ha->vport_slock, flags);
6896 vha->d_id = id;
6897 qlt_update_vp_map(vha, SET_AL_PA);
6898 spin_unlock_irqrestore(&ha->vport_slock, flags);
6899 } else if (vha->d_id.b24 != id.b24) {
6900 spin_lock_irqsave(&ha->vport_slock, flags);
6901 qlt_update_vp_map(vha, RESET_AL_PA);
6902 vha->d_id = id;
6903 qlt_update_vp_map(vha, SET_AL_PA);
6904 spin_unlock_irqrestore(&ha->vport_slock, flags);
6905 }
6906}
6907
6842static int __init qlt_parse_ini_mode(void) 6908static int __init qlt_parse_ini_mode(void)
6843{ 6909{
6844 if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_EXCLUSIVE) == 0) 6910 if (strcasecmp(qlini_mode, QLA2XXX_INI_MODE_STR_EXCLUSIVE) == 0)