aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_transport_fc.c
diff options
context:
space:
mode:
authorFUJITA Tomonori <tomof@acm.org>2007-08-31 13:02:27 -0400
committerJames Bottomley <jejb@mulgrave.localdomain>2007-10-12 14:46:58 -0400
commit7525236d0bc7ad17eb5e0733417896cab745d6c8 (patch)
tree677fd3adae67e7f100c366955832e266f1515632 /drivers/scsi/scsi_transport_fc.c
parent5dc2b89e124251662f580f4ba3c9f6195d1eaff6 (diff)
[SCSI] fc_transport: add target driver support
This adds minimum target driver support like the srp transport does: - fc_remote_port_{rolechg,delete} calls scsi_tgt_it_nexus_{create,destroy} for target drivers. - add callbacks to notify target drivers of the nexus and tmf operation results to fc_function_template. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/scsi_transport_fc.c')
-rw-r--r--drivers/scsi/scsi_transport_fc.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index dd97f2652508..8df0f080997f 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -36,6 +36,7 @@
36#include <net/netlink.h> 36#include <net/netlink.h>
37#include <scsi/scsi_netlink_fc.h> 37#include <scsi/scsi_netlink_fc.h>
38#include "scsi_priv.h" 38#include "scsi_priv.h"
39#include "scsi_transport_fc_internal.h"
39 40
40static int fc_queue_work(struct Scsi_Host *, struct work_struct *); 41static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
41static void fc_vport_sched_delete(struct work_struct *work); 42static void fc_vport_sched_delete(struct work_struct *work);
@@ -1956,6 +1957,19 @@ static int fc_user_scan(struct Scsi_Host *shost, uint channel,
1956 return 0; 1957 return 0;
1957} 1958}
1958 1959
1960static int fc_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id,
1961 int result)
1962{
1963 struct fc_internal *i = to_fc_internal(shost->transportt);
1964 return i->f->tsk_mgmt_response(shost, nexus, tm_id, result);
1965}
1966
1967static int fc_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result)
1968{
1969 struct fc_internal *i = to_fc_internal(shost->transportt);
1970 return i->f->it_nexus_response(shost, nexus, result);
1971}
1972
1959struct scsi_transport_template * 1973struct scsi_transport_template *
1960fc_attach_transport(struct fc_function_template *ft) 1974fc_attach_transport(struct fc_function_template *ft)
1961{ 1975{
@@ -1999,6 +2013,10 @@ fc_attach_transport(struct fc_function_template *ft)
1999 2013
2000 i->t.user_scan = fc_user_scan; 2014 i->t.user_scan = fc_user_scan;
2001 2015
2016 /* target-mode drivers' functions */
2017 i->t.tsk_mgmt_response = fc_tsk_mgmt_response;
2018 i->t.it_nexus_response = fc_it_nexus_response;
2019
2002 /* 2020 /*
2003 * Setup SCSI Target Attributes. 2021 * Setup SCSI Target Attributes.
2004 */ 2022 */
@@ -2756,6 +2774,10 @@ fc_remote_port_delete(struct fc_rport *rport)
2756 2774
2757 spin_unlock_irqrestore(shost->host_lock, flags); 2775 spin_unlock_irqrestore(shost->host_lock, flags);
2758 2776
2777 if (rport->roles & FC_PORT_ROLE_FCP_INITIATOR &&
2778 shost->active_mode & MODE_TARGET)
2779 fc_tgt_it_nexus_destroy(shost, (unsigned long)rport);
2780
2759 scsi_target_block(&rport->dev); 2781 scsi_target_block(&rport->dev);
2760 2782
2761 /* see if we need to kill io faster than waiting for device loss */ 2783 /* see if we need to kill io faster than waiting for device loss */
@@ -2796,6 +2818,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
2796 struct fc_host_attrs *fc_host = shost_to_fc_host(shost); 2818 struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
2797 unsigned long flags; 2819 unsigned long flags;
2798 int create = 0; 2820 int create = 0;
2821 int ret;
2799 2822
2800 spin_lock_irqsave(shost->host_lock, flags); 2823 spin_lock_irqsave(shost->host_lock, flags);
2801 if (roles & FC_PORT_ROLE_FCP_TARGET) { 2824 if (roles & FC_PORT_ROLE_FCP_TARGET) {
@@ -2804,6 +2827,12 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
2804 create = 1; 2827 create = 1;
2805 } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET)) 2828 } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET))
2806 create = 1; 2829 create = 1;
2830 } else if (shost->active_mode & MODE_TARGET) {
2831 ret = fc_tgt_it_nexus_create(shost, (unsigned long)rport,
2832 (char *)&rport->node_name);
2833 if (ret)
2834 printk(KERN_ERR "FC Remore Port tgt nexus failed %d\n",
2835 ret);
2807 } 2836 }
2808 2837
2809 rport->roles = roles; 2838 rport->roles = roles;