diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-31 18:31:23 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-31 18:31:23 -0500 |
commit | 4e13c5d0212f25d69a97606b9d5a85edb52a7737 (patch) | |
tree | 002f59b9151f42a6388656762f0e7963d08b89ef /drivers/scsi | |
parent | deb2a1d29bf0168ff2575e714e5c1f156be663fb (diff) | |
parent | 5259a06ef97068b710f45d092a587e8d740f750f (diff) |
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending
Pull SCSI target updates from Nicholas Bellinger:
"The highlights this round include:
- add support for SCSI Referrals (Hannes)
- add support for T10 DIF into target core (nab + mkp)
- add support for T10 DIF emulation in FILEIO + RAMDISK backends (Sagi + nab)
- add support for T10 DIF -> bio_integrity passthrough in IBLOCK backend (nab)
- prep changes to iser-target for >= v3.15 T10 DIF support (Sagi)
- add support for qla2xxx N_Port ID Virtualization - NPIV (Saurav + Quinn)
- allow percpu_ida_alloc() to receive task state bitmask (Kent)
- fix >= v3.12 iscsi-target session reset hung task regression (nab)
- fix >= v3.13 percpu_ref se_lun->lun_ref_active race (nab)
- fix a long-standing network portal creation race (Andy)"
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target-pending: (51 commits)
target: Fix percpu_ref_put race in transport_lun_remove_cmd
target/iscsi: Fix network portal creation race
target: Report bad sector in sense data for DIF errors
iscsi-target: Convert gfp_t parameter to task state bitmask
iscsi-target: Fix connection reset hang with percpu_ida_alloc
percpu_ida: Make percpu_ida_alloc + callers accept task state bitmask
iscsi-target: Pre-allocate more tags to avoid ack starvation
qla2xxx: Configure NPIV fc_vport via tcm_qla2xxx_npiv_make_lport
qla2xxx: Enhancements to enable NPIV support for QLOGIC ISPs with TCM/LIO.
qla2xxx: Fix scsi_host leak on qlt_lport_register callback failure
IB/isert: pass scatterlist instead of cmd to fast_reg_mr routine
IB/isert: Move fastreg descriptor creation to a function
IB/isert: Avoid frwr notation, user fastreg
IB/isert: seperate connection protection domains and dma MRs
tcm_loop: Enable DIF/DIX modes in SCSI host LLD
target/rd: Add DIF protection into rd_execute_rw
target/rd: Add support for protection SGL setup + release
target/rd: Refactor rd_build_device_space + rd_release_device_space
target/file: Add DIF protection support to fd_execute_rw
target/file: Add DIF protection init/format support
...
Diffstat (limited to 'drivers/scsi')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_attr.c | 2 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_def.h | 12 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.c | 171 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/qla_target.h | 4 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/tcm_qla2xxx.c | 180 | ||||
-rw-r--r-- | drivers/scsi/qla2xxx/tcm_qla2xxx.h | 4 |
6 files changed, 221 insertions, 152 deletions
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 570c7fcc0c4d..4a0d7c92181f 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -1990,6 +1990,8 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) | |||
1990 | 1990 | ||
1991 | vha->flags.delete_progress = 1; | 1991 | vha->flags.delete_progress = 1; |
1992 | 1992 | ||
1993 | qlt_remove_target(ha, vha); | ||
1994 | |||
1993 | fc_remove_host(vha->host); | 1995 | fc_remove_host(vha->host); |
1994 | 1996 | ||
1995 | scsi_remove_host(vha->host); | 1997 | scsi_remove_host(vha->host); |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 41d6491d7bd9..e1fe95ef23e1 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2750,6 +2750,13 @@ struct qlfc_fw { | |||
2750 | uint32_t len; | 2750 | uint32_t len; |
2751 | }; | 2751 | }; |
2752 | 2752 | ||
2753 | struct scsi_qlt_host { | ||
2754 | void *target_lport_ptr; | ||
2755 | struct mutex tgt_mutex; | ||
2756 | struct mutex tgt_host_action_mutex; | ||
2757 | struct qla_tgt *qla_tgt; | ||
2758 | }; | ||
2759 | |||
2753 | struct qlt_hw_data { | 2760 | struct qlt_hw_data { |
2754 | /* Protected by hw lock */ | 2761 | /* Protected by hw lock */ |
2755 | uint32_t enable_class_2:1; | 2762 | uint32_t enable_class_2:1; |
@@ -2765,15 +2772,11 @@ struct qlt_hw_data { | |||
2765 | uint32_t __iomem *atio_q_in; | 2772 | uint32_t __iomem *atio_q_in; |
2766 | uint32_t __iomem *atio_q_out; | 2773 | uint32_t __iomem *atio_q_out; |
2767 | 2774 | ||
2768 | void *target_lport_ptr; | ||
2769 | struct qla_tgt_func_tmpl *tgt_ops; | 2775 | struct qla_tgt_func_tmpl *tgt_ops; |
2770 | struct qla_tgt *qla_tgt; | ||
2771 | struct qla_tgt_cmd *cmds[DEFAULT_OUTSTANDING_COMMANDS]; | 2776 | struct qla_tgt_cmd *cmds[DEFAULT_OUTSTANDING_COMMANDS]; |
2772 | uint16_t current_handle; | 2777 | uint16_t current_handle; |
2773 | 2778 | ||
2774 | struct qla_tgt_vp_map *tgt_vp_map; | 2779 | struct qla_tgt_vp_map *tgt_vp_map; |
2775 | struct mutex tgt_mutex; | ||
2776 | struct mutex tgt_host_action_mutex; | ||
2777 | 2780 | ||
2778 | int saved_set; | 2781 | int saved_set; |
2779 | uint16_t saved_exchange_count; | 2782 | uint16_t saved_exchange_count; |
@@ -3435,6 +3438,7 @@ typedef struct scsi_qla_host { | |||
3435 | #define VP_ERR_FAB_LOGOUT 4 | 3438 | #define VP_ERR_FAB_LOGOUT 4 |
3436 | #define VP_ERR_ADAP_NORESOURCES 5 | 3439 | #define VP_ERR_ADAP_NORESOURCES 5 |
3437 | struct qla_hw_data *hw; | 3440 | struct qla_hw_data *hw; |
3441 | struct scsi_qlt_host vha_tgt; | ||
3438 | struct req_que *req; | 3442 | struct req_que *req; |
3439 | int fw_heartbeat_counter; | 3443 | int fw_heartbeat_counter; |
3440 | int seconds_since_last_heartbeat; | 3444 | int seconds_since_last_heartbeat; |
diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 38a1257e76e1..9e80d61e5a3a 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c | |||
@@ -590,7 +590,7 @@ static struct qla_tgt_sess *qlt_create_sess( | |||
590 | 590 | ||
591 | /* Check to avoid double sessions */ | 591 | /* Check to avoid double sessions */ |
592 | spin_lock_irqsave(&ha->hardware_lock, flags); | 592 | spin_lock_irqsave(&ha->hardware_lock, flags); |
593 | list_for_each_entry(sess, &ha->tgt.qla_tgt->sess_list, | 593 | list_for_each_entry(sess, &vha->vha_tgt.qla_tgt->sess_list, |
594 | sess_list_entry) { | 594 | sess_list_entry) { |
595 | if (!memcmp(sess->port_name, fcport->port_name, WWN_SIZE)) { | 595 | if (!memcmp(sess->port_name, fcport->port_name, WWN_SIZE)) { |
596 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf005, | 596 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf005, |
@@ -627,7 +627,7 @@ static struct qla_tgt_sess *qlt_create_sess( | |||
627 | 627 | ||
628 | return NULL; | 628 | return NULL; |
629 | } | 629 | } |
630 | sess->tgt = ha->tgt.qla_tgt; | 630 | sess->tgt = vha->vha_tgt.qla_tgt; |
631 | sess->vha = vha; | 631 | sess->vha = vha; |
632 | sess->s_id = fcport->d_id; | 632 | sess->s_id = fcport->d_id; |
633 | sess->loop_id = fcport->loop_id; | 633 | sess->loop_id = fcport->loop_id; |
@@ -635,7 +635,7 @@ static struct qla_tgt_sess *qlt_create_sess( | |||
635 | 635 | ||
636 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf006, | 636 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf006, |
637 | "Adding sess %p to tgt %p via ->check_initiator_node_acl()\n", | 637 | "Adding sess %p to tgt %p via ->check_initiator_node_acl()\n", |
638 | sess, ha->tgt.qla_tgt); | 638 | sess, vha->vha_tgt.qla_tgt); |
639 | 639 | ||
640 | be_sid[0] = sess->s_id.b.domain; | 640 | be_sid[0] = sess->s_id.b.domain; |
641 | be_sid[1] = sess->s_id.b.area; | 641 | be_sid[1] = sess->s_id.b.area; |
@@ -662,8 +662,8 @@ static struct qla_tgt_sess *qlt_create_sess( | |||
662 | memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); | 662 | memcpy(sess->port_name, fcport->port_name, sizeof(sess->port_name)); |
663 | 663 | ||
664 | spin_lock_irqsave(&ha->hardware_lock, flags); | 664 | spin_lock_irqsave(&ha->hardware_lock, flags); |
665 | list_add_tail(&sess->sess_list_entry, &ha->tgt.qla_tgt->sess_list); | 665 | list_add_tail(&sess->sess_list_entry, &vha->vha_tgt.qla_tgt->sess_list); |
666 | ha->tgt.qla_tgt->sess_count++; | 666 | vha->vha_tgt.qla_tgt->sess_count++; |
667 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 667 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
668 | 668 | ||
669 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04b, | 669 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04b, |
@@ -682,7 +682,7 @@ static struct qla_tgt_sess *qlt_create_sess( | |||
682 | void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) | 682 | void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) |
683 | { | 683 | { |
684 | struct qla_hw_data *ha = vha->hw; | 684 | struct qla_hw_data *ha = vha->hw; |
685 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | 685 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
686 | struct qla_tgt_sess *sess; | 686 | struct qla_tgt_sess *sess; |
687 | unsigned long flags; | 687 | unsigned long flags; |
688 | 688 | ||
@@ -692,6 +692,9 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
692 | if (!tgt || (fcport->port_type != FCT_INITIATOR)) | 692 | if (!tgt || (fcport->port_type != FCT_INITIATOR)) |
693 | return; | 693 | return; |
694 | 694 | ||
695 | if (qla_ini_mode_enabled(vha)) | ||
696 | return; | ||
697 | |||
695 | spin_lock_irqsave(&ha->hardware_lock, flags); | 698 | spin_lock_irqsave(&ha->hardware_lock, flags); |
696 | if (tgt->tgt_stop) { | 699 | if (tgt->tgt_stop) { |
697 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 700 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
@@ -701,9 +704,9 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
701 | if (!sess) { | 704 | if (!sess) { |
702 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 705 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
703 | 706 | ||
704 | mutex_lock(&ha->tgt.tgt_mutex); | 707 | mutex_lock(&vha->vha_tgt.tgt_mutex); |
705 | sess = qlt_create_sess(vha, fcport, false); | 708 | sess = qlt_create_sess(vha, fcport, false); |
706 | mutex_unlock(&ha->tgt.tgt_mutex); | 709 | mutex_unlock(&vha->vha_tgt.tgt_mutex); |
707 | 710 | ||
708 | spin_lock_irqsave(&ha->hardware_lock, flags); | 711 | spin_lock_irqsave(&ha->hardware_lock, flags); |
709 | } else { | 712 | } else { |
@@ -739,7 +742,7 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport) | |||
739 | void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport) | 742 | void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport) |
740 | { | 743 | { |
741 | struct qla_hw_data *ha = vha->hw; | 744 | struct qla_hw_data *ha = vha->hw; |
742 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | 745 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
743 | struct qla_tgt_sess *sess; | 746 | struct qla_tgt_sess *sess; |
744 | unsigned long flags; | 747 | unsigned long flags; |
745 | 748 | ||
@@ -806,12 +809,12 @@ void qlt_stop_phase1(struct qla_tgt *tgt) | |||
806 | * Mutex needed to sync with qla_tgt_fc_port_[added,deleted]. | 809 | * Mutex needed to sync with qla_tgt_fc_port_[added,deleted]. |
807 | * Lock is needed, because we still can get an incoming packet. | 810 | * Lock is needed, because we still can get an incoming packet. |
808 | */ | 811 | */ |
809 | mutex_lock(&ha->tgt.tgt_mutex); | 812 | mutex_lock(&vha->vha_tgt.tgt_mutex); |
810 | spin_lock_irqsave(&ha->hardware_lock, flags); | 813 | spin_lock_irqsave(&ha->hardware_lock, flags); |
811 | tgt->tgt_stop = 1; | 814 | tgt->tgt_stop = 1; |
812 | qlt_clear_tgt_db(tgt, true); | 815 | qlt_clear_tgt_db(tgt, true); |
813 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 816 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
814 | mutex_unlock(&ha->tgt.tgt_mutex); | 817 | mutex_unlock(&vha->vha_tgt.tgt_mutex); |
815 | 818 | ||
816 | flush_delayed_work(&tgt->sess_del_work); | 819 | flush_delayed_work(&tgt->sess_del_work); |
817 | 820 | ||
@@ -845,20 +848,21 @@ EXPORT_SYMBOL(qlt_stop_phase1); | |||
845 | void qlt_stop_phase2(struct qla_tgt *tgt) | 848 | void qlt_stop_phase2(struct qla_tgt *tgt) |
846 | { | 849 | { |
847 | struct qla_hw_data *ha = tgt->ha; | 850 | struct qla_hw_data *ha = tgt->ha; |
851 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | ||
848 | unsigned long flags; | 852 | unsigned long flags; |
849 | 853 | ||
850 | if (tgt->tgt_stopped) { | 854 | if (tgt->tgt_stopped) { |
851 | ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf04f, | 855 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04f, |
852 | "Already in tgt->tgt_stopped state\n"); | 856 | "Already in tgt->tgt_stopped state\n"); |
853 | dump_stack(); | 857 | dump_stack(); |
854 | return; | 858 | return; |
855 | } | 859 | } |
856 | 860 | ||
857 | ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00b, | 861 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00b, |
858 | "Waiting for %d IRQ commands to complete (tgt %p)", | 862 | "Waiting for %d IRQ commands to complete (tgt %p)", |
859 | tgt->irq_cmd_count, tgt); | 863 | tgt->irq_cmd_count, tgt); |
860 | 864 | ||
861 | mutex_lock(&ha->tgt.tgt_mutex); | 865 | mutex_lock(&vha->vha_tgt.tgt_mutex); |
862 | spin_lock_irqsave(&ha->hardware_lock, flags); | 866 | spin_lock_irqsave(&ha->hardware_lock, flags); |
863 | while (tgt->irq_cmd_count != 0) { | 867 | while (tgt->irq_cmd_count != 0) { |
864 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 868 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
@@ -868,9 +872,9 @@ void qlt_stop_phase2(struct qla_tgt *tgt) | |||
868 | tgt->tgt_stop = 0; | 872 | tgt->tgt_stop = 0; |
869 | tgt->tgt_stopped = 1; | 873 | tgt->tgt_stopped = 1; |
870 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 874 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
871 | mutex_unlock(&ha->tgt.tgt_mutex); | 875 | mutex_unlock(&vha->vha_tgt.tgt_mutex); |
872 | 876 | ||
873 | ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00c, "Stop of tgt %p finished", | 877 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00c, "Stop of tgt %p finished", |
874 | tgt); | 878 | tgt); |
875 | } | 879 | } |
876 | EXPORT_SYMBOL(qlt_stop_phase2); | 880 | EXPORT_SYMBOL(qlt_stop_phase2); |
@@ -878,14 +882,14 @@ EXPORT_SYMBOL(qlt_stop_phase2); | |||
878 | /* Called from qlt_remove_target() -> qla2x00_remove_one() */ | 882 | /* Called from qlt_remove_target() -> qla2x00_remove_one() */ |
879 | static void qlt_release(struct qla_tgt *tgt) | 883 | static void qlt_release(struct qla_tgt *tgt) |
880 | { | 884 | { |
881 | struct qla_hw_data *ha = tgt->ha; | 885 | scsi_qla_host_t *vha = tgt->vha; |
882 | 886 | ||
883 | if ((ha->tgt.qla_tgt != NULL) && !tgt->tgt_stopped) | 887 | if ((vha->vha_tgt.qla_tgt != NULL) && !tgt->tgt_stopped) |
884 | qlt_stop_phase2(tgt); | 888 | qlt_stop_phase2(tgt); |
885 | 889 | ||
886 | ha->tgt.qla_tgt = NULL; | 890 | vha->vha_tgt.qla_tgt = NULL; |
887 | 891 | ||
888 | ql_dbg(ql_dbg_tgt_mgt, tgt->vha, 0xf00d, | 892 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00d, |
889 | "Release of tgt %p finished\n", tgt); | 893 | "Release of tgt %p finished\n", tgt); |
890 | 894 | ||
891 | kfree(tgt); | 895 | kfree(tgt); |
@@ -949,8 +953,8 @@ static void qlt_send_notify_ack(struct scsi_qla_host *vha, | |||
949 | return; | 953 | return; |
950 | } | 954 | } |
951 | 955 | ||
952 | if (ha->tgt.qla_tgt != NULL) | 956 | if (vha->vha_tgt.qla_tgt != NULL) |
953 | ha->tgt.qla_tgt->notify_ack_expected++; | 957 | vha->vha_tgt.qla_tgt->notify_ack_expected++; |
954 | 958 | ||
955 | pkt->entry_type = NOTIFY_ACK_TYPE; | 959 | pkt->entry_type = NOTIFY_ACK_TYPE; |
956 | pkt->entry_count = 1; | 960 | pkt->entry_count = 1; |
@@ -1054,7 +1058,7 @@ static void qlt_24xx_send_abts_resp(struct scsi_qla_host *vha, | |||
1054 | /* Other bytes are zero */ | 1058 | /* Other bytes are zero */ |
1055 | } | 1059 | } |
1056 | 1060 | ||
1057 | ha->tgt.qla_tgt->abts_resp_expected++; | 1061 | vha->vha_tgt.qla_tgt->abts_resp_expected++; |
1058 | 1062 | ||
1059 | qla2x00_start_iocbs(vha, vha->req); | 1063 | qla2x00_start_iocbs(vha, vha->req); |
1060 | } | 1064 | } |
@@ -1206,7 +1210,7 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha, | |||
1206 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf012, | 1210 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf012, |
1207 | "qla_target(%d): task abort for non-existant session\n", | 1211 | "qla_target(%d): task abort for non-existant session\n", |
1208 | vha->vp_idx); | 1212 | vha->vp_idx); |
1209 | rc = qlt_sched_sess_work(ha->tgt.qla_tgt, | 1213 | rc = qlt_sched_sess_work(vha->vha_tgt.qla_tgt, |
1210 | QLA_TGT_SESS_WORK_ABORT, abts, sizeof(*abts)); | 1214 | QLA_TGT_SESS_WORK_ABORT, abts, sizeof(*abts)); |
1211 | if (rc != 0) { | 1215 | if (rc != 0) { |
1212 | qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, | 1216 | qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, |
@@ -2157,8 +2161,7 @@ static int qlt_prepare_srr_ctio(struct scsi_qla_host *vha, | |||
2157 | struct qla_tgt_cmd *cmd, void *ctio) | 2161 | struct qla_tgt_cmd *cmd, void *ctio) |
2158 | { | 2162 | { |
2159 | struct qla_tgt_srr_ctio *sc; | 2163 | struct qla_tgt_srr_ctio *sc; |
2160 | struct qla_hw_data *ha = vha->hw; | 2164 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
2161 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | ||
2162 | struct qla_tgt_srr_imm *imm; | 2165 | struct qla_tgt_srr_imm *imm; |
2163 | 2166 | ||
2164 | tgt->ctio_srr_id++; | 2167 | tgt->ctio_srr_id++; |
@@ -2474,7 +2477,7 @@ static void qlt_do_work(struct work_struct *work) | |||
2474 | struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); | 2477 | struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work); |
2475 | scsi_qla_host_t *vha = cmd->vha; | 2478 | scsi_qla_host_t *vha = cmd->vha; |
2476 | struct qla_hw_data *ha = vha->hw; | 2479 | struct qla_hw_data *ha = vha->hw; |
2477 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | 2480 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
2478 | struct qla_tgt_sess *sess = NULL; | 2481 | struct qla_tgt_sess *sess = NULL; |
2479 | struct atio_from_isp *atio = &cmd->atio; | 2482 | struct atio_from_isp *atio = &cmd->atio; |
2480 | unsigned char *cdb; | 2483 | unsigned char *cdb; |
@@ -2507,10 +2510,10 @@ static void qlt_do_work(struct work_struct *work) | |||
2507 | goto out_term; | 2510 | goto out_term; |
2508 | } | 2511 | } |
2509 | 2512 | ||
2510 | mutex_lock(&ha->tgt.tgt_mutex); | 2513 | mutex_lock(&vha->vha_tgt.tgt_mutex); |
2511 | sess = qlt_make_local_sess(vha, s_id); | 2514 | sess = qlt_make_local_sess(vha, s_id); |
2512 | /* sess has an extra creation ref. */ | 2515 | /* sess has an extra creation ref. */ |
2513 | mutex_unlock(&ha->tgt.tgt_mutex); | 2516 | mutex_unlock(&vha->vha_tgt.tgt_mutex); |
2514 | 2517 | ||
2515 | if (!sess) | 2518 | if (!sess) |
2516 | goto out_term; | 2519 | goto out_term; |
@@ -2576,8 +2579,7 @@ out_term: | |||
2576 | static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, | 2579 | static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, |
2577 | struct atio_from_isp *atio) | 2580 | struct atio_from_isp *atio) |
2578 | { | 2581 | { |
2579 | struct qla_hw_data *ha = vha->hw; | 2582 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
2580 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | ||
2581 | struct qla_tgt_cmd *cmd; | 2583 | struct qla_tgt_cmd *cmd; |
2582 | 2584 | ||
2583 | if (unlikely(tgt->tgt_stop)) { | 2585 | if (unlikely(tgt->tgt_stop)) { |
@@ -2597,7 +2599,7 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha, | |||
2597 | 2599 | ||
2598 | memcpy(&cmd->atio, atio, sizeof(*atio)); | 2600 | memcpy(&cmd->atio, atio, sizeof(*atio)); |
2599 | cmd->state = QLA_TGT_STATE_NEW; | 2601 | cmd->state = QLA_TGT_STATE_NEW; |
2600 | cmd->tgt = ha->tgt.qla_tgt; | 2602 | cmd->tgt = vha->vha_tgt.qla_tgt; |
2601 | cmd->vha = vha; | 2603 | cmd->vha = vha; |
2602 | 2604 | ||
2603 | INIT_WORK(&cmd->work, qlt_do_work); | 2605 | INIT_WORK(&cmd->work, qlt_do_work); |
@@ -2723,7 +2725,7 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host *vha, void *iocb) | |||
2723 | uint32_t lun, unpacked_lun; | 2725 | uint32_t lun, unpacked_lun; |
2724 | int lun_size, fn; | 2726 | int lun_size, fn; |
2725 | 2727 | ||
2726 | tgt = ha->tgt.qla_tgt; | 2728 | tgt = vha->vha_tgt.qla_tgt; |
2727 | 2729 | ||
2728 | lun = a->u.isp24.fcp_cmnd.lun; | 2730 | lun = a->u.isp24.fcp_cmnd.lun; |
2729 | lun_size = sizeof(a->u.isp24.fcp_cmnd.lun); | 2731 | lun_size = sizeof(a->u.isp24.fcp_cmnd.lun); |
@@ -2797,7 +2799,7 @@ static int qlt_abort_task(struct scsi_qla_host *vha, | |||
2797 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf025, | 2799 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf025, |
2798 | "qla_target(%d): task abort for unexisting " | 2800 | "qla_target(%d): task abort for unexisting " |
2799 | "session\n", vha->vp_idx); | 2801 | "session\n", vha->vp_idx); |
2800 | return qlt_sched_sess_work(ha->tgt.qla_tgt, | 2802 | return qlt_sched_sess_work(vha->vha_tgt.qla_tgt, |
2801 | QLA_TGT_SESS_WORK_ABORT, iocb, sizeof(*iocb)); | 2803 | QLA_TGT_SESS_WORK_ABORT, iocb, sizeof(*iocb)); |
2802 | } | 2804 | } |
2803 | 2805 | ||
@@ -2810,7 +2812,6 @@ static int qlt_abort_task(struct scsi_qla_host *vha, | |||
2810 | static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | 2812 | static int qlt_24xx_handle_els(struct scsi_qla_host *vha, |
2811 | struct imm_ntfy_from_isp *iocb) | 2813 | struct imm_ntfy_from_isp *iocb) |
2812 | { | 2814 | { |
2813 | struct qla_hw_data *ha = vha->hw; | ||
2814 | int res = 0; | 2815 | int res = 0; |
2815 | 2816 | ||
2816 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf026, | 2817 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf026, |
@@ -2828,7 +2829,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha, | |||
2828 | case ELS_PDISC: | 2829 | case ELS_PDISC: |
2829 | case ELS_ADISC: | 2830 | case ELS_ADISC: |
2830 | { | 2831 | { |
2831 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | 2832 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
2832 | if (tgt->link_reinit_iocb_pending) { | 2833 | if (tgt->link_reinit_iocb_pending) { |
2833 | qlt_send_notify_ack(vha, &tgt->link_reinit_iocb, | 2834 | qlt_send_notify_ack(vha, &tgt->link_reinit_iocb, |
2834 | 0, 0, 0, 0, 0, 0); | 2835 | 0, 0, 0, 0, 0, 0); |
@@ -3202,8 +3203,7 @@ static void qlt_prepare_srr_imm(struct scsi_qla_host *vha, | |||
3202 | struct imm_ntfy_from_isp *iocb) | 3203 | struct imm_ntfy_from_isp *iocb) |
3203 | { | 3204 | { |
3204 | struct qla_tgt_srr_imm *imm; | 3205 | struct qla_tgt_srr_imm *imm; |
3205 | struct qla_hw_data *ha = vha->hw; | 3206 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
3206 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | ||
3207 | struct qla_tgt_srr_ctio *sctio; | 3207 | struct qla_tgt_srr_ctio *sctio; |
3208 | 3208 | ||
3209 | tgt->imm_srr_id++; | 3209 | tgt->imm_srr_id++; |
@@ -3313,7 +3313,7 @@ static void qlt_handle_imm_notify(struct scsi_qla_host *vha, | |||
3313 | 3313 | ||
3314 | case IMM_NTFY_LIP_LINK_REINIT: | 3314 | case IMM_NTFY_LIP_LINK_REINIT: |
3315 | { | 3315 | { |
3316 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | 3316 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
3317 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf033, | 3317 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf033, |
3318 | "qla_target(%d): LINK REINIT (loop %#x, " | 3318 | "qla_target(%d): LINK REINIT (loop %#x, " |
3319 | "subcode %x)\n", vha->vp_idx, | 3319 | "subcode %x)\n", vha->vp_idx, |
@@ -3489,7 +3489,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
3489 | struct atio_from_isp *atio) | 3489 | struct atio_from_isp *atio) |
3490 | { | 3490 | { |
3491 | struct qla_hw_data *ha = vha->hw; | 3491 | struct qla_hw_data *ha = vha->hw; |
3492 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | 3492 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
3493 | int rc; | 3493 | int rc; |
3494 | 3494 | ||
3495 | if (unlikely(tgt == NULL)) { | 3495 | if (unlikely(tgt == NULL)) { |
@@ -3591,7 +3591,7 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, | |||
3591 | static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) | 3591 | static void qlt_response_pkt(struct scsi_qla_host *vha, response_t *pkt) |
3592 | { | 3592 | { |
3593 | struct qla_hw_data *ha = vha->hw; | 3593 | struct qla_hw_data *ha = vha->hw; |
3594 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | 3594 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
3595 | 3595 | ||
3596 | if (unlikely(tgt == NULL)) { | 3596 | if (unlikely(tgt == NULL)) { |
3597 | ql_dbg(ql_dbg_tgt, vha, 0xe05d, | 3597 | ql_dbg(ql_dbg_tgt, vha, 0xe05d, |
@@ -3794,7 +3794,7 @@ void qlt_async_event(uint16_t code, struct scsi_qla_host *vha, | |||
3794 | uint16_t *mailbox) | 3794 | uint16_t *mailbox) |
3795 | { | 3795 | { |
3796 | struct qla_hw_data *ha = vha->hw; | 3796 | struct qla_hw_data *ha = vha->hw; |
3797 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | 3797 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
3798 | int login_code; | 3798 | int login_code; |
3799 | 3799 | ||
3800 | ql_dbg(ql_dbg_tgt, vha, 0xe039, | 3800 | ql_dbg(ql_dbg_tgt, vha, 0xe039, |
@@ -3924,14 +3924,14 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha, | |||
3924 | static struct qla_tgt_sess *qlt_make_local_sess(struct scsi_qla_host *vha, | 3924 | static struct qla_tgt_sess *qlt_make_local_sess(struct scsi_qla_host *vha, |
3925 | uint8_t *s_id) | 3925 | uint8_t *s_id) |
3926 | { | 3926 | { |
3927 | struct qla_hw_data *ha = vha->hw; | ||
3928 | struct qla_tgt_sess *sess = NULL; | 3927 | struct qla_tgt_sess *sess = NULL; |
3929 | fc_port_t *fcport = NULL; | 3928 | fc_port_t *fcport = NULL; |
3930 | int rc, global_resets; | 3929 | int rc, global_resets; |
3931 | uint16_t loop_id = 0; | 3930 | uint16_t loop_id = 0; |
3932 | 3931 | ||
3933 | retry: | 3932 | retry: |
3934 | global_resets = atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count); | 3933 | global_resets = |
3934 | atomic_read(&vha->vha_tgt.qla_tgt->tgt_global_resets_count); | ||
3935 | 3935 | ||
3936 | rc = qla24xx_get_loop_id(vha, s_id, &loop_id); | 3936 | rc = qla24xx_get_loop_id(vha, s_id, &loop_id); |
3937 | if (rc != 0) { | 3937 | if (rc != 0) { |
@@ -3958,12 +3958,13 @@ retry: | |||
3958 | return NULL; | 3958 | return NULL; |
3959 | 3959 | ||
3960 | if (global_resets != | 3960 | if (global_resets != |
3961 | atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)) { | 3961 | atomic_read(&vha->vha_tgt.qla_tgt->tgt_global_resets_count)) { |
3962 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf043, | 3962 | ql_dbg(ql_dbg_tgt_mgt, vha, 0xf043, |
3963 | "qla_target(%d): global reset during session discovery " | 3963 | "qla_target(%d): global reset during session discovery " |
3964 | "(counter was %d, new %d), retrying", vha->vp_idx, | 3964 | "(counter was %d, new %d), retrying", vha->vp_idx, |
3965 | global_resets, | 3965 | global_resets, |
3966 | atomic_read(&ha->tgt.qla_tgt->tgt_global_resets_count)); | 3966 | atomic_read(&vha->vha_tgt. |
3967 | qla_tgt->tgt_global_resets_count)); | ||
3967 | goto retry; | 3968 | goto retry; |
3968 | } | 3969 | } |
3969 | 3970 | ||
@@ -3998,10 +3999,10 @@ static void qlt_abort_work(struct qla_tgt *tgt, | |||
3998 | if (!sess) { | 3999 | if (!sess) { |
3999 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4000 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4000 | 4001 | ||
4001 | mutex_lock(&ha->tgt.tgt_mutex); | 4002 | mutex_lock(&vha->vha_tgt.tgt_mutex); |
4002 | sess = qlt_make_local_sess(vha, s_id); | 4003 | sess = qlt_make_local_sess(vha, s_id); |
4003 | /* sess has got an extra creation ref */ | 4004 | /* sess has got an extra creation ref */ |
4004 | mutex_unlock(&ha->tgt.tgt_mutex); | 4005 | mutex_unlock(&vha->vha_tgt.tgt_mutex); |
4005 | 4006 | ||
4006 | spin_lock_irqsave(&ha->hardware_lock, flags); | 4007 | spin_lock_irqsave(&ha->hardware_lock, flags); |
4007 | if (!sess) | 4008 | if (!sess) |
@@ -4052,10 +4053,10 @@ static void qlt_tmr_work(struct qla_tgt *tgt, | |||
4052 | if (!sess) { | 4053 | if (!sess) { |
4053 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4054 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4054 | 4055 | ||
4055 | mutex_lock(&ha->tgt.tgt_mutex); | 4056 | mutex_lock(&vha->vha_tgt.tgt_mutex); |
4056 | sess = qlt_make_local_sess(vha, s_id); | 4057 | sess = qlt_make_local_sess(vha, s_id); |
4057 | /* sess has got an extra creation ref */ | 4058 | /* sess has got an extra creation ref */ |
4058 | mutex_unlock(&ha->tgt.tgt_mutex); | 4059 | mutex_unlock(&vha->vha_tgt.tgt_mutex); |
4059 | 4060 | ||
4060 | spin_lock_irqsave(&ha->hardware_lock, flags); | 4061 | spin_lock_irqsave(&ha->hardware_lock, flags); |
4061 | if (!sess) | 4062 | if (!sess) |
@@ -4141,9 +4142,9 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) | |||
4141 | } | 4142 | } |
4142 | 4143 | ||
4143 | ql_dbg(ql_dbg_tgt, base_vha, 0xe03b, | 4144 | ql_dbg(ql_dbg_tgt, base_vha, 0xe03b, |
4144 | "Registering target for host %ld(%p)", base_vha->host_no, ha); | 4145 | "Registering target for host %ld(%p).\n", base_vha->host_no, ha); |
4145 | 4146 | ||
4146 | BUG_ON((ha->tgt.qla_tgt != NULL) || (ha->tgt.tgt_ops != NULL)); | 4147 | BUG_ON(base_vha->vha_tgt.qla_tgt != NULL); |
4147 | 4148 | ||
4148 | tgt = kzalloc(sizeof(struct qla_tgt), GFP_KERNEL); | 4149 | tgt = kzalloc(sizeof(struct qla_tgt), GFP_KERNEL); |
4149 | if (!tgt) { | 4150 | if (!tgt) { |
@@ -4171,7 +4172,7 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) | |||
4171 | INIT_WORK(&tgt->srr_work, qlt_handle_srr_work); | 4172 | INIT_WORK(&tgt->srr_work, qlt_handle_srr_work); |
4172 | atomic_set(&tgt->tgt_global_resets_count, 0); | 4173 | atomic_set(&tgt->tgt_global_resets_count, 0); |
4173 | 4174 | ||
4174 | ha->tgt.qla_tgt = tgt; | 4175 | base_vha->vha_tgt.qla_tgt = tgt; |
4175 | 4176 | ||
4176 | ql_dbg(ql_dbg_tgt, base_vha, 0xe067, | 4177 | ql_dbg(ql_dbg_tgt, base_vha, 0xe067, |
4177 | "qla_target(%d): using 64 Bit PCI addressing", | 4178 | "qla_target(%d): using 64 Bit PCI addressing", |
@@ -4192,16 +4193,16 @@ int qlt_add_target(struct qla_hw_data *ha, struct scsi_qla_host *base_vha) | |||
4192 | /* Must be called under tgt_host_action_mutex */ | 4193 | /* Must be called under tgt_host_action_mutex */ |
4193 | int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha) | 4194 | int qlt_remove_target(struct qla_hw_data *ha, struct scsi_qla_host *vha) |
4194 | { | 4195 | { |
4195 | if (!ha->tgt.qla_tgt) | 4196 | if (!vha->vha_tgt.qla_tgt) |
4196 | return 0; | 4197 | return 0; |
4197 | 4198 | ||
4198 | mutex_lock(&qla_tgt_mutex); | 4199 | mutex_lock(&qla_tgt_mutex); |
4199 | list_del(&ha->tgt.qla_tgt->tgt_list_entry); | 4200 | list_del(&vha->vha_tgt.qla_tgt->tgt_list_entry); |
4200 | mutex_unlock(&qla_tgt_mutex); | 4201 | mutex_unlock(&qla_tgt_mutex); |
4201 | 4202 | ||
4202 | ql_dbg(ql_dbg_tgt, vha, 0xe03c, "Unregistering target for host %ld(%p)", | 4203 | ql_dbg(ql_dbg_tgt, vha, 0xe03c, "Unregistering target for host %ld(%p)", |
4203 | vha->host_no, ha); | 4204 | vha->host_no, ha); |
4204 | qlt_release(ha->tgt.qla_tgt); | 4205 | qlt_release(vha->vha_tgt.qla_tgt); |
4205 | 4206 | ||
4206 | return 0; | 4207 | return 0; |
4207 | } | 4208 | } |
@@ -4235,8 +4236,9 @@ static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, | |||
4235 | * @callback: lport initialization callback for tcm_qla2xxx code | 4236 | * @callback: lport initialization callback for tcm_qla2xxx code |
4236 | * @target_lport_ptr: pointer for tcm_qla2xxx specific lport data | 4237 | * @target_lport_ptr: pointer for tcm_qla2xxx specific lport data |
4237 | */ | 4238 | */ |
4238 | int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn, | 4239 | int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, |
4239 | int (*callback)(struct scsi_qla_host *), void *target_lport_ptr) | 4240 | u64 npiv_wwpn, u64 npiv_wwnn, |
4241 | int (*callback)(struct scsi_qla_host *, void *, u64, u64)) | ||
4240 | { | 4242 | { |
4241 | struct qla_tgt *tgt; | 4243 | struct qla_tgt *tgt; |
4242 | struct scsi_qla_host *vha; | 4244 | struct scsi_qla_host *vha; |
@@ -4255,14 +4257,11 @@ int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn, | |||
4255 | if (!host) | 4257 | if (!host) |
4256 | continue; | 4258 | continue; |
4257 | 4259 | ||
4258 | if (ha->tgt.tgt_ops != NULL) | ||
4259 | continue; | ||
4260 | |||
4261 | if (!(host->hostt->supported_mode & MODE_TARGET)) | 4260 | if (!(host->hostt->supported_mode & MODE_TARGET)) |
4262 | continue; | 4261 | continue; |
4263 | 4262 | ||
4264 | spin_lock_irqsave(&ha->hardware_lock, flags); | 4263 | spin_lock_irqsave(&ha->hardware_lock, flags); |
4265 | if (host->active_mode & MODE_TARGET) { | 4264 | if ((!npiv_wwpn || !npiv_wwnn) && host->active_mode & MODE_TARGET) { |
4266 | pr_debug("MODE_TARGET already active on qla2xxx(%d)\n", | 4265 | pr_debug("MODE_TARGET already active on qla2xxx(%d)\n", |
4267 | host->host_no); | 4266 | host->host_no); |
4268 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4267 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
@@ -4276,24 +4275,18 @@ int qlt_lport_register(struct qla_tgt_func_tmpl *qla_tgt_ops, u64 wwpn, | |||
4276 | " qla2xxx scsi_host\n"); | 4275 | " qla2xxx scsi_host\n"); |
4277 | continue; | 4276 | continue; |
4278 | } | 4277 | } |
4279 | qlt_lport_dump(vha, wwpn, b); | 4278 | qlt_lport_dump(vha, phys_wwpn, b); |
4280 | 4279 | ||
4281 | if (memcmp(vha->port_name, b, WWN_SIZE)) { | 4280 | if (memcmp(vha->port_name, b, WWN_SIZE)) { |
4282 | scsi_host_put(host); | 4281 | scsi_host_put(host); |
4283 | continue; | 4282 | continue; |
4284 | } | 4283 | } |
4285 | /* | ||
4286 | * Setup passed parameters ahead of invoking callback | ||
4287 | */ | ||
4288 | ha->tgt.tgt_ops = qla_tgt_ops; | ||
4289 | ha->tgt.target_lport_ptr = target_lport_ptr; | ||
4290 | rc = (*callback)(vha); | ||
4291 | if (rc != 0) { | ||
4292 | ha->tgt.tgt_ops = NULL; | ||
4293 | ha->tgt.target_lport_ptr = NULL; | ||
4294 | scsi_host_put(host); | ||
4295 | } | ||
4296 | mutex_unlock(&qla_tgt_mutex); | 4284 | mutex_unlock(&qla_tgt_mutex); |
4285 | |||
4286 | rc = (*callback)(vha, target_lport_ptr, npiv_wwpn, npiv_wwnn); | ||
4287 | if (rc != 0) | ||
4288 | scsi_host_put(host); | ||
4289 | |||
4297 | return rc; | 4290 | return rc; |
4298 | } | 4291 | } |
4299 | mutex_unlock(&qla_tgt_mutex); | 4292 | mutex_unlock(&qla_tgt_mutex); |
@@ -4314,7 +4307,7 @@ void qlt_lport_deregister(struct scsi_qla_host *vha) | |||
4314 | /* | 4307 | /* |
4315 | * Clear the target_lport_ptr qla_target_template pointer in qla_hw_data | 4308 | * Clear the target_lport_ptr qla_target_template pointer in qla_hw_data |
4316 | */ | 4309 | */ |
4317 | ha->tgt.target_lport_ptr = NULL; | 4310 | vha->vha_tgt.target_lport_ptr = NULL; |
4318 | ha->tgt.tgt_ops = NULL; | 4311 | ha->tgt.tgt_ops = NULL; |
4319 | /* | 4312 | /* |
4320 | * Release the Scsi_Host reference for the underlying qla2xxx host | 4313 | * Release the Scsi_Host reference for the underlying qla2xxx host |
@@ -4376,8 +4369,9 @@ void | |||
4376 | qlt_enable_vha(struct scsi_qla_host *vha) | 4369 | qlt_enable_vha(struct scsi_qla_host *vha) |
4377 | { | 4370 | { |
4378 | struct qla_hw_data *ha = vha->hw; | 4371 | struct qla_hw_data *ha = vha->hw; |
4379 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | 4372 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
4380 | unsigned long flags; | 4373 | unsigned long flags; |
4374 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | ||
4381 | 4375 | ||
4382 | if (!tgt) { | 4376 | if (!tgt) { |
4383 | ql_dbg(ql_dbg_tgt, vha, 0xe069, | 4377 | ql_dbg(ql_dbg_tgt, vha, 0xe069, |
@@ -4392,9 +4386,14 @@ qlt_enable_vha(struct scsi_qla_host *vha) | |||
4392 | qlt_set_mode(vha); | 4386 | qlt_set_mode(vha); |
4393 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 4387 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
4394 | 4388 | ||
4395 | set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); | 4389 | if (vha->vp_idx) { |
4396 | qla2xxx_wake_dpc(vha); | 4390 | qla24xx_disable_vp(vha); |
4397 | qla2x00_wait_for_hba_online(vha); | 4391 | qla24xx_enable_vp(vha); |
4392 | } else { | ||
4393 | set_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags); | ||
4394 | qla2xxx_wake_dpc(base_vha); | ||
4395 | qla2x00_wait_for_hba_online(base_vha); | ||
4396 | } | ||
4398 | } | 4397 | } |
4399 | EXPORT_SYMBOL(qlt_enable_vha); | 4398 | EXPORT_SYMBOL(qlt_enable_vha); |
4400 | 4399 | ||
@@ -4407,7 +4406,7 @@ void | |||
4407 | qlt_disable_vha(struct scsi_qla_host *vha) | 4406 | qlt_disable_vha(struct scsi_qla_host *vha) |
4408 | { | 4407 | { |
4409 | struct qla_hw_data *ha = vha->hw; | 4408 | struct qla_hw_data *ha = vha->hw; |
4410 | struct qla_tgt *tgt = ha->tgt.qla_tgt; | 4409 | struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; |
4411 | unsigned long flags; | 4410 | unsigned long flags; |
4412 | 4411 | ||
4413 | if (!tgt) { | 4412 | if (!tgt) { |
@@ -4438,8 +4437,10 @@ qlt_vport_create(struct scsi_qla_host *vha, struct qla_hw_data *ha) | |||
4438 | if (!qla_tgt_mode_enabled(vha)) | 4437 | if (!qla_tgt_mode_enabled(vha)) |
4439 | return; | 4438 | return; |
4440 | 4439 | ||
4441 | mutex_init(&ha->tgt.tgt_mutex); | 4440 | vha->vha_tgt.qla_tgt = NULL; |
4442 | mutex_init(&ha->tgt.tgt_host_action_mutex); | 4441 | |
4442 | mutex_init(&vha->vha_tgt.tgt_mutex); | ||
4443 | mutex_init(&vha->vha_tgt.tgt_host_action_mutex); | ||
4443 | 4444 | ||
4444 | qlt_clear_mode(vha); | 4445 | qlt_clear_mode(vha); |
4445 | 4446 | ||
@@ -4450,6 +4451,8 @@ qlt_vport_create(struct scsi_qla_host *vha, struct qla_hw_data *ha) | |||
4450 | * assigning the value appropriately. | 4451 | * assigning the value appropriately. |
4451 | */ | 4452 | */ |
4452 | ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; | 4453 | ha->tgt.atio_q_length = ATIO_ENTRY_CNT_24XX; |
4454 | |||
4455 | qlt_add_target(ha, vha); | ||
4453 | } | 4456 | } |
4454 | 4457 | ||
4455 | void | 4458 | void |
@@ -4768,8 +4771,8 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha) | |||
4768 | ISP_ATIO_Q_OUT(base_vha) = &ha->iobase->isp24.atio_q_out; | 4771 | ISP_ATIO_Q_OUT(base_vha) = &ha->iobase->isp24.atio_q_out; |
4769 | } | 4772 | } |
4770 | 4773 | ||
4771 | mutex_init(&ha->tgt.tgt_mutex); | 4774 | mutex_init(&base_vha->vha_tgt.tgt_mutex); |
4772 | mutex_init(&ha->tgt.tgt_host_action_mutex); | 4775 | mutex_init(&base_vha->vha_tgt.tgt_host_action_mutex); |
4773 | qlt_clear_mode(base_vha); | 4776 | qlt_clear_mode(base_vha); |
4774 | } | 4777 | } |
4775 | 4778 | ||
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index b33e411f28a0..1d10eecad499 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h | |||
@@ -932,8 +932,8 @@ void qlt_disable_vha(struct scsi_qla_host *); | |||
932 | */ | 932 | */ |
933 | extern int qlt_add_target(struct qla_hw_data *, struct scsi_qla_host *); | 933 | extern int qlt_add_target(struct qla_hw_data *, struct scsi_qla_host *); |
934 | extern int qlt_remove_target(struct qla_hw_data *, struct scsi_qla_host *); | 934 | extern int qlt_remove_target(struct qla_hw_data *, struct scsi_qla_host *); |
935 | extern int qlt_lport_register(struct qla_tgt_func_tmpl *, u64, | 935 | extern int qlt_lport_register(void *, u64, u64, u64, |
936 | int (*callback)(struct scsi_qla_host *), void *); | 936 | int (*callback)(struct scsi_qla_host *, void *, u64, u64)); |
937 | extern void qlt_lport_deregister(struct scsi_qla_host *); | 937 | extern void qlt_lport_deregister(struct scsi_qla_host *); |
938 | extern void qlt_unreg_sess(struct qla_tgt_sess *); | 938 | extern void qlt_unreg_sess(struct qla_tgt_sess *); |
939 | extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *); | 939 | extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *); |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c index 7eb19be35d46..75a141bbe74d 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c | |||
@@ -53,16 +53,6 @@ | |||
53 | struct workqueue_struct *tcm_qla2xxx_free_wq; | 53 | struct workqueue_struct *tcm_qla2xxx_free_wq; |
54 | struct workqueue_struct *tcm_qla2xxx_cmd_wq; | 54 | struct workqueue_struct *tcm_qla2xxx_cmd_wq; |
55 | 55 | ||
56 | static int tcm_qla2xxx_check_true(struct se_portal_group *se_tpg) | ||
57 | { | ||
58 | return 1; | ||
59 | } | ||
60 | |||
61 | static int tcm_qla2xxx_check_false(struct se_portal_group *se_tpg) | ||
62 | { | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | /* | 56 | /* |
67 | * Parse WWN. | 57 | * Parse WWN. |
68 | * If strict, we require lower-case hex and colon separators to be sure | 58 | * If strict, we require lower-case hex and colon separators to be sure |
@@ -174,7 +164,7 @@ static int tcm_qla2xxx_npiv_parse_wwn( | |||
174 | *wwnn = 0; | 164 | *wwnn = 0; |
175 | 165 | ||
176 | /* count may include a LF at end of string */ | 166 | /* count may include a LF at end of string */ |
177 | if (name[cnt-1] == '\n') | 167 | if (name[cnt-1] == '\n' || name[cnt-1] == 0) |
178 | cnt--; | 168 | cnt--; |
179 | 169 | ||
180 | /* validate we have enough characters for WWPN */ | 170 | /* validate we have enough characters for WWPN */ |
@@ -777,6 +767,9 @@ static void tcm_qla2xxx_put_session(struct se_session *se_sess) | |||
777 | 767 | ||
778 | static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess) | 768 | static void tcm_qla2xxx_put_sess(struct qla_tgt_sess *sess) |
779 | { | 769 | { |
770 | if (!sess) | ||
771 | return; | ||
772 | |||
780 | assert_spin_locked(&sess->vha->hw->hardware_lock); | 773 | assert_spin_locked(&sess->vha->hw->hardware_lock); |
781 | kref_put(&sess->se_sess->sess_kref, tcm_qla2xxx_release_session); | 774 | kref_put(&sess->se_sess->sess_kref, tcm_qla2xxx_release_session); |
782 | } | 775 | } |
@@ -957,7 +950,6 @@ static ssize_t tcm_qla2xxx_tpg_store_enable( | |||
957 | struct tcm_qla2xxx_lport *lport = container_of(se_wwn, | 950 | struct tcm_qla2xxx_lport *lport = container_of(se_wwn, |
958 | struct tcm_qla2xxx_lport, lport_wwn); | 951 | struct tcm_qla2xxx_lport, lport_wwn); |
959 | struct scsi_qla_host *vha = lport->qla_vha; | 952 | struct scsi_qla_host *vha = lport->qla_vha; |
960 | struct qla_hw_data *ha = vha->hw; | ||
961 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, | 953 | struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg, |
962 | struct tcm_qla2xxx_tpg, se_tpg); | 954 | struct tcm_qla2xxx_tpg, se_tpg); |
963 | unsigned long op; | 955 | unsigned long op; |
@@ -977,12 +969,12 @@ static ssize_t tcm_qla2xxx_tpg_store_enable( | |||
977 | atomic_set(&tpg->lport_tpg_enabled, 1); | 969 | atomic_set(&tpg->lport_tpg_enabled, 1); |
978 | qlt_enable_vha(vha); | 970 | qlt_enable_vha(vha); |
979 | } else { | 971 | } else { |
980 | if (!ha->tgt.qla_tgt) { | 972 | if (!vha->vha_tgt.qla_tgt) { |
981 | pr_err("truct qla_hw_data *ha->tgt.qla_tgt is NULL\n"); | 973 | pr_err("struct qla_hw_data *vha->vha_tgt.qla_tgt is NULL\n"); |
982 | return -ENODEV; | 974 | return -ENODEV; |
983 | } | 975 | } |
984 | atomic_set(&tpg->lport_tpg_enabled, 0); | 976 | atomic_set(&tpg->lport_tpg_enabled, 0); |
985 | qlt_stop_phase1(ha->tgt.qla_tgt); | 977 | qlt_stop_phase1(vha->vha_tgt.qla_tgt); |
986 | } | 978 | } |
987 | 979 | ||
988 | return count; | 980 | return count; |
@@ -1011,7 +1003,7 @@ static struct se_portal_group *tcm_qla2xxx_make_tpg( | |||
1011 | if (kstrtoul(name + 5, 10, &tpgt) || tpgt > USHRT_MAX) | 1003 | if (kstrtoul(name + 5, 10, &tpgt) || tpgt > USHRT_MAX) |
1012 | return ERR_PTR(-EINVAL); | 1004 | return ERR_PTR(-EINVAL); |
1013 | 1005 | ||
1014 | if (!lport->qla_npiv_vp && (tpgt != 1)) { | 1006 | if ((tpgt != 1)) { |
1015 | pr_err("In non NPIV mode, a single TPG=1 is used for HW port mappings\n"); | 1007 | pr_err("In non NPIV mode, a single TPG=1 is used for HW port mappings\n"); |
1016 | return ERR_PTR(-ENOSYS); | 1008 | return ERR_PTR(-ENOSYS); |
1017 | } | 1009 | } |
@@ -1038,11 +1030,8 @@ static struct se_portal_group *tcm_qla2xxx_make_tpg( | |||
1038 | kfree(tpg); | 1030 | kfree(tpg); |
1039 | return NULL; | 1031 | return NULL; |
1040 | } | 1032 | } |
1041 | /* | 1033 | |
1042 | * Setup local TPG=1 pointer for non NPIV mode. | 1034 | lport->tpg_1 = tpg; |
1043 | */ | ||
1044 | if (lport->qla_npiv_vp == NULL) | ||
1045 | lport->tpg_1 = tpg; | ||
1046 | 1035 | ||
1047 | return &tpg->se_tpg; | 1036 | return &tpg->se_tpg; |
1048 | } | 1037 | } |
@@ -1053,19 +1042,17 @@ static void tcm_qla2xxx_drop_tpg(struct se_portal_group *se_tpg) | |||
1053 | struct tcm_qla2xxx_tpg, se_tpg); | 1042 | struct tcm_qla2xxx_tpg, se_tpg); |
1054 | struct tcm_qla2xxx_lport *lport = tpg->lport; | 1043 | struct tcm_qla2xxx_lport *lport = tpg->lport; |
1055 | struct scsi_qla_host *vha = lport->qla_vha; | 1044 | struct scsi_qla_host *vha = lport->qla_vha; |
1056 | struct qla_hw_data *ha = vha->hw; | ||
1057 | /* | 1045 | /* |
1058 | * Call into qla2x_target.c LLD logic to shutdown the active | 1046 | * Call into qla2x_target.c LLD logic to shutdown the active |
1059 | * FC Nexuses and disable target mode operation for this qla_hw_data | 1047 | * FC Nexuses and disable target mode operation for this qla_hw_data |
1060 | */ | 1048 | */ |
1061 | if (ha->tgt.qla_tgt && !ha->tgt.qla_tgt->tgt_stop) | 1049 | if (vha->vha_tgt.qla_tgt && !vha->vha_tgt.qla_tgt->tgt_stop) |
1062 | qlt_stop_phase1(ha->tgt.qla_tgt); | 1050 | qlt_stop_phase1(vha->vha_tgt.qla_tgt); |
1063 | 1051 | ||
1064 | core_tpg_deregister(se_tpg); | 1052 | core_tpg_deregister(se_tpg); |
1065 | /* | 1053 | /* |
1066 | * Clear local TPG=1 pointer for non NPIV mode. | 1054 | * Clear local TPG=1 pointer for non NPIV mode. |
1067 | */ | 1055 | */ |
1068 | if (lport->qla_npiv_vp == NULL) | ||
1069 | lport->tpg_1 = NULL; | 1056 | lport->tpg_1 = NULL; |
1070 | 1057 | ||
1071 | kfree(tpg); | 1058 | kfree(tpg); |
@@ -1095,12 +1082,22 @@ static struct se_portal_group *tcm_qla2xxx_npiv_make_tpg( | |||
1095 | tpg->lport = lport; | 1082 | tpg->lport = lport; |
1096 | tpg->lport_tpgt = tpgt; | 1083 | tpg->lport_tpgt = tpgt; |
1097 | 1084 | ||
1085 | /* | ||
1086 | * By default allow READ-ONLY TPG demo-mode access w/ cached dynamic | ||
1087 | * NodeACLs | ||
1088 | */ | ||
1089 | tpg->tpg_attrib.generate_node_acls = 1; | ||
1090 | tpg->tpg_attrib.demo_mode_write_protect = 1; | ||
1091 | tpg->tpg_attrib.cache_dynamic_acls = 1; | ||
1092 | tpg->tpg_attrib.demo_mode_login_only = 1; | ||
1093 | |||
1098 | ret = core_tpg_register(&tcm_qla2xxx_npiv_fabric_configfs->tf_ops, wwn, | 1094 | ret = core_tpg_register(&tcm_qla2xxx_npiv_fabric_configfs->tf_ops, wwn, |
1099 | &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); | 1095 | &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); |
1100 | if (ret < 0) { | 1096 | if (ret < 0) { |
1101 | kfree(tpg); | 1097 | kfree(tpg); |
1102 | return NULL; | 1098 | return NULL; |
1103 | } | 1099 | } |
1100 | lport->tpg_1 = tpg; | ||
1104 | return &tpg->se_tpg; | 1101 | return &tpg->se_tpg; |
1105 | } | 1102 | } |
1106 | 1103 | ||
@@ -1111,13 +1108,12 @@ static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_s_id( | |||
1111 | scsi_qla_host_t *vha, | 1108 | scsi_qla_host_t *vha, |
1112 | const uint8_t *s_id) | 1109 | const uint8_t *s_id) |
1113 | { | 1110 | { |
1114 | struct qla_hw_data *ha = vha->hw; | ||
1115 | struct tcm_qla2xxx_lport *lport; | 1111 | struct tcm_qla2xxx_lport *lport; |
1116 | struct se_node_acl *se_nacl; | 1112 | struct se_node_acl *se_nacl; |
1117 | struct tcm_qla2xxx_nacl *nacl; | 1113 | struct tcm_qla2xxx_nacl *nacl; |
1118 | u32 key; | 1114 | u32 key; |
1119 | 1115 | ||
1120 | lport = ha->tgt.target_lport_ptr; | 1116 | lport = vha->vha_tgt.target_lport_ptr; |
1121 | if (!lport) { | 1117 | if (!lport) { |
1122 | pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); | 1118 | pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); |
1123 | dump_stack(); | 1119 | dump_stack(); |
@@ -1221,13 +1217,12 @@ static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_loop_id( | |||
1221 | scsi_qla_host_t *vha, | 1217 | scsi_qla_host_t *vha, |
1222 | const uint16_t loop_id) | 1218 | const uint16_t loop_id) |
1223 | { | 1219 | { |
1224 | struct qla_hw_data *ha = vha->hw; | ||
1225 | struct tcm_qla2xxx_lport *lport; | 1220 | struct tcm_qla2xxx_lport *lport; |
1226 | struct se_node_acl *se_nacl; | 1221 | struct se_node_acl *se_nacl; |
1227 | struct tcm_qla2xxx_nacl *nacl; | 1222 | struct tcm_qla2xxx_nacl *nacl; |
1228 | struct tcm_qla2xxx_fc_loopid *fc_loopid; | 1223 | struct tcm_qla2xxx_fc_loopid *fc_loopid; |
1229 | 1224 | ||
1230 | lport = ha->tgt.target_lport_ptr; | 1225 | lport = vha->vha_tgt.target_lport_ptr; |
1231 | if (!lport) { | 1226 | if (!lport) { |
1232 | pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); | 1227 | pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); |
1233 | dump_stack(); | 1228 | dump_stack(); |
@@ -1341,6 +1336,7 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) | |||
1341 | { | 1336 | { |
1342 | struct qla_tgt *tgt = sess->tgt; | 1337 | struct qla_tgt *tgt = sess->tgt; |
1343 | struct qla_hw_data *ha = tgt->ha; | 1338 | struct qla_hw_data *ha = tgt->ha; |
1339 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); | ||
1344 | struct se_session *se_sess; | 1340 | struct se_session *se_sess; |
1345 | struct se_node_acl *se_nacl; | 1341 | struct se_node_acl *se_nacl; |
1346 | struct tcm_qla2xxx_lport *lport; | 1342 | struct tcm_qla2xxx_lport *lport; |
@@ -1357,7 +1353,7 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess) | |||
1357 | se_nacl = se_sess->se_node_acl; | 1353 | se_nacl = se_sess->se_node_acl; |
1358 | nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); | 1354 | nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl); |
1359 | 1355 | ||
1360 | lport = ha->tgt.target_lport_ptr; | 1356 | lport = vha->vha_tgt.target_lport_ptr; |
1361 | if (!lport) { | 1357 | if (!lport) { |
1362 | pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); | 1358 | pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); |
1363 | dump_stack(); | 1359 | dump_stack(); |
@@ -1391,7 +1387,7 @@ static int tcm_qla2xxx_check_initiator_node_acl( | |||
1391 | unsigned char port_name[36]; | 1387 | unsigned char port_name[36]; |
1392 | unsigned long flags; | 1388 | unsigned long flags; |
1393 | 1389 | ||
1394 | lport = ha->tgt.target_lport_ptr; | 1390 | lport = vha->vha_tgt.target_lport_ptr; |
1395 | if (!lport) { | 1391 | if (!lport) { |
1396 | pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); | 1392 | pr_err("Unable to locate struct tcm_qla2xxx_lport\n"); |
1397 | dump_stack(); | 1393 | dump_stack(); |
@@ -1455,7 +1451,8 @@ static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id, | |||
1455 | { | 1451 | { |
1456 | struct qla_tgt *tgt = sess->tgt; | 1452 | struct qla_tgt *tgt = sess->tgt; |
1457 | struct qla_hw_data *ha = tgt->ha; | 1453 | struct qla_hw_data *ha = tgt->ha; |
1458 | struct tcm_qla2xxx_lport *lport = ha->tgt.target_lport_ptr; | 1454 | scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); |
1455 | struct tcm_qla2xxx_lport *lport = vha->vha_tgt.target_lport_ptr; | ||
1459 | struct se_node_acl *se_nacl = sess->se_sess->se_node_acl; | 1456 | struct se_node_acl *se_nacl = sess->se_sess->se_node_acl; |
1460 | struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, | 1457 | struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl, |
1461 | struct tcm_qla2xxx_nacl, se_node_acl); | 1458 | struct tcm_qla2xxx_nacl, se_node_acl); |
@@ -1562,15 +1559,18 @@ static int tcm_qla2xxx_init_lport(struct tcm_qla2xxx_lport *lport) | |||
1562 | return 0; | 1559 | return 0; |
1563 | } | 1560 | } |
1564 | 1561 | ||
1565 | static int tcm_qla2xxx_lport_register_cb(struct scsi_qla_host *vha) | 1562 | static int tcm_qla2xxx_lport_register_cb(struct scsi_qla_host *vha, |
1563 | void *target_lport_ptr, | ||
1564 | u64 npiv_wwpn, u64 npiv_wwnn) | ||
1566 | { | 1565 | { |
1567 | struct qla_hw_data *ha = vha->hw; | 1566 | struct qla_hw_data *ha = vha->hw; |
1568 | struct tcm_qla2xxx_lport *lport; | 1567 | struct tcm_qla2xxx_lport *lport = |
1568 | (struct tcm_qla2xxx_lport *)target_lport_ptr; | ||
1569 | /* | 1569 | /* |
1570 | * Setup local pointer to vha, NPIV VP pointer (if present) and | 1570 | * Setup tgt_ops, local pointer to vha and target_lport_ptr |
1571 | * vha->tcm_lport pointer | ||
1572 | */ | 1571 | */ |
1573 | lport = (struct tcm_qla2xxx_lport *)ha->tgt.target_lport_ptr; | 1572 | ha->tgt.tgt_ops = &tcm_qla2xxx_template; |
1573 | vha->vha_tgt.target_lport_ptr = target_lport_ptr; | ||
1574 | lport->qla_vha = vha; | 1574 | lport->qla_vha = vha; |
1575 | 1575 | ||
1576 | return 0; | 1576 | return 0; |
@@ -1602,8 +1602,8 @@ static struct se_wwn *tcm_qla2xxx_make_lport( | |||
1602 | if (ret != 0) | 1602 | if (ret != 0) |
1603 | goto out; | 1603 | goto out; |
1604 | 1604 | ||
1605 | ret = qlt_lport_register(&tcm_qla2xxx_template, wwpn, | 1605 | ret = qlt_lport_register(lport, wwpn, 0, 0, |
1606 | tcm_qla2xxx_lport_register_cb, lport); | 1606 | tcm_qla2xxx_lport_register_cb); |
1607 | if (ret != 0) | 1607 | if (ret != 0) |
1608 | goto out_lport; | 1608 | goto out_lport; |
1609 | 1609 | ||
@@ -1621,7 +1621,6 @@ static void tcm_qla2xxx_drop_lport(struct se_wwn *wwn) | |||
1621 | struct tcm_qla2xxx_lport *lport = container_of(wwn, | 1621 | struct tcm_qla2xxx_lport *lport = container_of(wwn, |
1622 | struct tcm_qla2xxx_lport, lport_wwn); | 1622 | struct tcm_qla2xxx_lport, lport_wwn); |
1623 | struct scsi_qla_host *vha = lport->qla_vha; | 1623 | struct scsi_qla_host *vha = lport->qla_vha; |
1624 | struct qla_hw_data *ha = vha->hw; | ||
1625 | struct se_node_acl *node; | 1624 | struct se_node_acl *node; |
1626 | u32 key = 0; | 1625 | u32 key = 0; |
1627 | 1626 | ||
@@ -1630,8 +1629,8 @@ static void tcm_qla2xxx_drop_lport(struct se_wwn *wwn) | |||
1630 | * shutdown of struct qla_tgt after the call to | 1629 | * shutdown of struct qla_tgt after the call to |
1631 | * qlt_stop_phase1() from tcm_qla2xxx_drop_tpg() above.. | 1630 | * qlt_stop_phase1() from tcm_qla2xxx_drop_tpg() above.. |
1632 | */ | 1631 | */ |
1633 | if (ha->tgt.qla_tgt && !ha->tgt.qla_tgt->tgt_stopped) | 1632 | if (vha->vha_tgt.qla_tgt && !vha->vha_tgt.qla_tgt->tgt_stopped) |
1634 | qlt_stop_phase2(ha->tgt.qla_tgt); | 1633 | qlt_stop_phase2(vha->vha_tgt.qla_tgt); |
1635 | 1634 | ||
1636 | qlt_lport_deregister(vha); | 1635 | qlt_lport_deregister(vha); |
1637 | 1636 | ||
@@ -1642,17 +1641,70 @@ static void tcm_qla2xxx_drop_lport(struct se_wwn *wwn) | |||
1642 | kfree(lport); | 1641 | kfree(lport); |
1643 | } | 1642 | } |
1644 | 1643 | ||
1644 | static int tcm_qla2xxx_lport_register_npiv_cb(struct scsi_qla_host *base_vha, | ||
1645 | void *target_lport_ptr, | ||
1646 | u64 npiv_wwpn, u64 npiv_wwnn) | ||
1647 | { | ||
1648 | struct fc_vport *vport; | ||
1649 | struct Scsi_Host *sh = base_vha->host; | ||
1650 | struct scsi_qla_host *npiv_vha; | ||
1651 | struct tcm_qla2xxx_lport *lport = | ||
1652 | (struct tcm_qla2xxx_lport *)target_lport_ptr; | ||
1653 | struct fc_vport_identifiers vport_id; | ||
1654 | |||
1655 | if (!qla_tgt_mode_enabled(base_vha)) { | ||
1656 | pr_err("qla2xxx base_vha not enabled for target mode\n"); | ||
1657 | return -EPERM; | ||
1658 | } | ||
1659 | |||
1660 | memset(&vport_id, 0, sizeof(vport_id)); | ||
1661 | vport_id.port_name = npiv_wwpn; | ||
1662 | vport_id.node_name = npiv_wwnn; | ||
1663 | vport_id.roles = FC_PORT_ROLE_FCP_INITIATOR; | ||
1664 | vport_id.vport_type = FC_PORTTYPE_NPIV; | ||
1665 | vport_id.disable = false; | ||
1666 | |||
1667 | vport = fc_vport_create(sh, 0, &vport_id); | ||
1668 | if (!vport) { | ||
1669 | pr_err("fc_vport_create failed for qla2xxx_npiv\n"); | ||
1670 | return -ENODEV; | ||
1671 | } | ||
1672 | /* | ||
1673 | * Setup local pointer to NPIV vhba + target_lport_ptr | ||
1674 | */ | ||
1675 | npiv_vha = (struct scsi_qla_host *)vport->dd_data; | ||
1676 | npiv_vha->vha_tgt.target_lport_ptr = target_lport_ptr; | ||
1677 | lport->qla_vha = npiv_vha; | ||
1678 | |||
1679 | scsi_host_get(npiv_vha->host); | ||
1680 | return 0; | ||
1681 | } | ||
1682 | |||
1683 | |||
1645 | static struct se_wwn *tcm_qla2xxx_npiv_make_lport( | 1684 | static struct se_wwn *tcm_qla2xxx_npiv_make_lport( |
1646 | struct target_fabric_configfs *tf, | 1685 | struct target_fabric_configfs *tf, |
1647 | struct config_group *group, | 1686 | struct config_group *group, |
1648 | const char *name) | 1687 | const char *name) |
1649 | { | 1688 | { |
1650 | struct tcm_qla2xxx_lport *lport; | 1689 | struct tcm_qla2xxx_lport *lport; |
1651 | u64 npiv_wwpn, npiv_wwnn; | 1690 | u64 phys_wwpn, npiv_wwpn, npiv_wwnn; |
1691 | char *p, tmp[128]; | ||
1652 | int ret; | 1692 | int ret; |
1653 | 1693 | ||
1654 | if (tcm_qla2xxx_npiv_parse_wwn(name, strlen(name)+1, | 1694 | snprintf(tmp, 128, "%s", name); |
1655 | &npiv_wwpn, &npiv_wwnn) < 0) | 1695 | |
1696 | p = strchr(tmp, '@'); | ||
1697 | if (!p) { | ||
1698 | pr_err("Unable to locate NPIV '@' seperator\n"); | ||
1699 | return ERR_PTR(-EINVAL); | ||
1700 | } | ||
1701 | *p++ = '\0'; | ||
1702 | |||
1703 | if (tcm_qla2xxx_parse_wwn(tmp, &phys_wwpn, 1) < 0) | ||
1704 | return ERR_PTR(-EINVAL); | ||
1705 | |||
1706 | if (tcm_qla2xxx_npiv_parse_wwn(p, strlen(p)+1, | ||
1707 | &npiv_wwpn, &npiv_wwnn) < 0) | ||
1656 | return ERR_PTR(-EINVAL); | 1708 | return ERR_PTR(-EINVAL); |
1657 | 1709 | ||
1658 | lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL); | 1710 | lport = kzalloc(sizeof(struct tcm_qla2xxx_lport), GFP_KERNEL); |
@@ -1666,12 +1718,19 @@ static struct se_wwn *tcm_qla2xxx_npiv_make_lport( | |||
1666 | TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); | 1718 | TCM_QLA2XXX_NAMELEN, npiv_wwpn, npiv_wwnn); |
1667 | sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn); | 1719 | sprintf(lport->lport_naa_name, "naa.%016llx", (unsigned long long) npiv_wwpn); |
1668 | 1720 | ||
1669 | /* FIXME: tcm_qla2xxx_npiv_make_lport */ | 1721 | ret = tcm_qla2xxx_init_lport(lport); |
1670 | ret = -ENOSYS; | ||
1671 | if (ret != 0) | 1722 | if (ret != 0) |
1672 | goto out; | 1723 | goto out; |
1673 | 1724 | ||
1725 | ret = qlt_lport_register(lport, phys_wwpn, npiv_wwpn, npiv_wwnn, | ||
1726 | tcm_qla2xxx_lport_register_npiv_cb); | ||
1727 | if (ret != 0) | ||
1728 | goto out_lport; | ||
1729 | |||
1674 | return &lport->lport_wwn; | 1730 | return &lport->lport_wwn; |
1731 | out_lport: | ||
1732 | vfree(lport->lport_loopid_map); | ||
1733 | btree_destroy32(&lport->lport_fcport_map); | ||
1675 | out: | 1734 | out: |
1676 | kfree(lport); | 1735 | kfree(lport); |
1677 | return ERR_PTR(ret); | 1736 | return ERR_PTR(ret); |
@@ -1681,14 +1740,16 @@ static void tcm_qla2xxx_npiv_drop_lport(struct se_wwn *wwn) | |||
1681 | { | 1740 | { |
1682 | struct tcm_qla2xxx_lport *lport = container_of(wwn, | 1741 | struct tcm_qla2xxx_lport *lport = container_of(wwn, |
1683 | struct tcm_qla2xxx_lport, lport_wwn); | 1742 | struct tcm_qla2xxx_lport, lport_wwn); |
1684 | struct scsi_qla_host *vha = lport->qla_vha; | 1743 | struct scsi_qla_host *npiv_vha = lport->qla_vha; |
1685 | struct Scsi_Host *sh = vha->host; | 1744 | struct qla_hw_data *ha = npiv_vha->hw; |
1745 | scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev); | ||
1746 | |||
1747 | scsi_host_put(npiv_vha->host); | ||
1686 | /* | 1748 | /* |
1687 | * Notify libfc that we want to release the lport->npiv_vport | 1749 | * Notify libfc that we want to release the vha->fc_vport |
1688 | */ | 1750 | */ |
1689 | fc_vport_terminate(lport->npiv_vport); | 1751 | fc_vport_terminate(npiv_vha->fc_vport); |
1690 | 1752 | scsi_host_put(base_vha->host); | |
1691 | scsi_host_put(sh); | ||
1692 | kfree(lport); | 1753 | kfree(lport); |
1693 | } | 1754 | } |
1694 | 1755 | ||
@@ -1769,14 +1830,16 @@ static struct target_core_fabric_ops tcm_qla2xxx_npiv_ops = { | |||
1769 | .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id, | 1830 | .tpg_get_pr_transport_id = tcm_qla2xxx_get_pr_transport_id, |
1770 | .tpg_get_pr_transport_id_len = tcm_qla2xxx_get_pr_transport_id_len, | 1831 | .tpg_get_pr_transport_id_len = tcm_qla2xxx_get_pr_transport_id_len, |
1771 | .tpg_parse_pr_out_transport_id = tcm_qla2xxx_parse_pr_out_transport_id, | 1832 | .tpg_parse_pr_out_transport_id = tcm_qla2xxx_parse_pr_out_transport_id, |
1772 | .tpg_check_demo_mode = tcm_qla2xxx_check_false, | 1833 | .tpg_check_demo_mode = tcm_qla2xxx_check_demo_mode, |
1773 | .tpg_check_demo_mode_cache = tcm_qla2xxx_check_true, | 1834 | .tpg_check_demo_mode_cache = tcm_qla2xxx_check_demo_mode_cache, |
1774 | .tpg_check_demo_mode_write_protect = tcm_qla2xxx_check_true, | 1835 | .tpg_check_demo_mode_write_protect = tcm_qla2xxx_check_demo_mode, |
1775 | .tpg_check_prod_mode_write_protect = tcm_qla2xxx_check_false, | 1836 | .tpg_check_prod_mode_write_protect = |
1837 | tcm_qla2xxx_check_prod_write_protect, | ||
1776 | .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_demo_mode_login_only, | 1838 | .tpg_check_demo_mode_login_only = tcm_qla2xxx_check_demo_mode_login_only, |
1777 | .tpg_alloc_fabric_acl = tcm_qla2xxx_alloc_fabric_acl, | 1839 | .tpg_alloc_fabric_acl = tcm_qla2xxx_alloc_fabric_acl, |
1778 | .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, | 1840 | .tpg_release_fabric_acl = tcm_qla2xxx_release_fabric_acl, |
1779 | .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, | 1841 | .tpg_get_inst_index = tcm_qla2xxx_tpg_get_inst_index, |
1842 | .check_stop_free = tcm_qla2xxx_check_stop_free, | ||
1780 | .release_cmd = tcm_qla2xxx_release_cmd, | 1843 | .release_cmd = tcm_qla2xxx_release_cmd, |
1781 | .put_session = tcm_qla2xxx_put_session, | 1844 | .put_session = tcm_qla2xxx_put_session, |
1782 | .shutdown_session = tcm_qla2xxx_shutdown_session, | 1845 | .shutdown_session = tcm_qla2xxx_shutdown_session, |
@@ -1871,7 +1934,8 @@ static int tcm_qla2xxx_register_configfs(void) | |||
1871 | * Setup default attribute lists for various npiv_fabric->tf_cit_tmpl | 1934 | * Setup default attribute lists for various npiv_fabric->tf_cit_tmpl |
1872 | */ | 1935 | */ |
1873 | npiv_fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; | 1936 | npiv_fabric->tf_cit_tmpl.tfc_wwn_cit.ct_attrs = tcm_qla2xxx_wwn_attrs; |
1874 | npiv_fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = NULL; | 1937 | npiv_fabric->tf_cit_tmpl.tfc_tpg_base_cit.ct_attrs = |
1938 | tcm_qla2xxx_tpg_attrs; | ||
1875 | npiv_fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; | 1939 | npiv_fabric->tf_cit_tmpl.tfc_tpg_attrib_cit.ct_attrs = NULL; |
1876 | npiv_fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; | 1940 | npiv_fabric->tf_cit_tmpl.tfc_tpg_param_cit.ct_attrs = NULL; |
1877 | npiv_fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; | 1941 | npiv_fabric->tf_cit_tmpl.tfc_tpg_np_base_cit.ct_attrs = NULL; |
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/drivers/scsi/qla2xxx/tcm_qla2xxx.h index 771f7b816443..275d8b9a7a34 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.h | |||
@@ -70,12 +70,8 @@ struct tcm_qla2xxx_lport { | |||
70 | struct tcm_qla2xxx_fc_loopid *lport_loopid_map; | 70 | struct tcm_qla2xxx_fc_loopid *lport_loopid_map; |
71 | /* Pointer to struct scsi_qla_host from qla2xxx LLD */ | 71 | /* Pointer to struct scsi_qla_host from qla2xxx LLD */ |
72 | struct scsi_qla_host *qla_vha; | 72 | struct scsi_qla_host *qla_vha; |
73 | /* Pointer to struct scsi_qla_host for NPIV VP from qla2xxx LLD */ | ||
74 | struct scsi_qla_host *qla_npiv_vp; | ||
75 | /* Pointer to struct qla_tgt pointer */ | 73 | /* Pointer to struct qla_tgt pointer */ |
76 | struct qla_tgt lport_qla_tgt; | 74 | struct qla_tgt lport_qla_tgt; |
77 | /* Pointer to struct fc_vport for NPIV vport from libfc */ | ||
78 | struct fc_vport *npiv_vport; | ||
79 | /* Pointer to TPG=1 for non NPIV mode */ | 75 | /* Pointer to TPG=1 for non NPIV mode */ |
80 | struct tcm_qla2xxx_tpg *tpg_1; | 76 | struct tcm_qla2xxx_tpg *tpg_1; |
81 | /* Returned by tcm_qla2xxx_make_lport() */ | 77 | /* Returned by tcm_qla2xxx_make_lport() */ |