Commit 7525236d authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by James Bottomley

[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: default avatarFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: default avatarMike Christie <michaelc@cs.wisc.edu>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 5dc2b89e
...@@ -272,6 +272,13 @@ config SCSI_FC_ATTRS ...@@ -272,6 +272,13 @@ config SCSI_FC_ATTRS
each attached FiberChannel device to sysfs, say Y. each attached FiberChannel device to sysfs, say Y.
Otherwise, say N. Otherwise, say N.
config SCSI_FC_TGT_ATTRS
bool "SCSI target support for FiberChannel Transport Attributes"
depends on SCSI_FC_ATTRS
depends on SCSI_TGT = y || SCSI_TGT = SCSI_FC_ATTRS
help
If you want to use SCSI target mode drivers enable this option.
config SCSI_ISCSI_ATTRS config SCSI_ISCSI_ATTRS
tristate "iSCSI Transport Attributes" tristate "iSCSI Transport Attributes"
depends on SCSI && NET depends on SCSI && NET
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include <net/netlink.h> #include <net/netlink.h>
#include <scsi/scsi_netlink_fc.h> #include <scsi/scsi_netlink_fc.h>
#include "scsi_priv.h" #include "scsi_priv.h"
#include "scsi_transport_fc_internal.h"
static int fc_queue_work(struct Scsi_Host *, struct work_struct *); static int fc_queue_work(struct Scsi_Host *, struct work_struct *);
static void fc_vport_sched_delete(struct work_struct *work); static 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,6 +1957,19 @@ static int fc_user_scan(struct Scsi_Host *shost, uint channel,
return 0; return 0;
} }
static int fc_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id,
int result)
{
struct fc_internal *i = to_fc_internal(shost->transportt);
return i->f->tsk_mgmt_response(shost, nexus, tm_id, result);
}
static int fc_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result)
{
struct fc_internal *i = to_fc_internal(shost->transportt);
return i->f->it_nexus_response(shost, nexus, result);
}
struct scsi_transport_template * struct scsi_transport_template *
fc_attach_transport(struct fc_function_template *ft) fc_attach_transport(struct fc_function_template *ft)
{ {
...@@ -1999,6 +2013,10 @@ fc_attach_transport(struct fc_function_template *ft) ...@@ -1999,6 +2013,10 @@ fc_attach_transport(struct fc_function_template *ft)
i->t.user_scan = fc_user_scan; i->t.user_scan = fc_user_scan;
/* target-mode drivers' functions */
i->t.tsk_mgmt_response = fc_tsk_mgmt_response;
i->t.it_nexus_response = fc_it_nexus_response;
/* /*
* Setup SCSI Target Attributes. * Setup SCSI Target Attributes.
*/ */
...@@ -2756,6 +2774,10 @@ fc_remote_port_delete(struct fc_rport *rport) ...@@ -2756,6 +2774,10 @@ fc_remote_port_delete(struct fc_rport *rport)
spin_unlock_irqrestore(shost->host_lock, flags); spin_unlock_irqrestore(shost->host_lock, flags);
if (rport->roles & FC_PORT_ROLE_FCP_INITIATOR &&
shost->active_mode & MODE_TARGET)
fc_tgt_it_nexus_destroy(shost, (unsigned long)rport);
scsi_target_block(&rport->dev); scsi_target_block(&rport->dev);
/* see if we need to kill io faster than waiting for device loss */ /* 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,6 +2818,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
struct fc_host_attrs *fc_host = shost_to_fc_host(shost); struct fc_host_attrs *fc_host = shost_to_fc_host(shost);
unsigned long flags; unsigned long flags;
int create = 0; int create = 0;
int ret;
spin_lock_irqsave(shost->host_lock, flags); spin_lock_irqsave(shost->host_lock, flags);
if (roles & FC_PORT_ROLE_FCP_TARGET) { if (roles & FC_PORT_ROLE_FCP_TARGET) {
...@@ -2804,6 +2827,12 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) ...@@ -2804,6 +2827,12 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles)
create = 1; create = 1;
} else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET)) } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET))
create = 1; create = 1;
} else if (shost->active_mode & MODE_TARGET) {
ret = fc_tgt_it_nexus_create(shost, (unsigned long)rport,
(char *)&rport->node_name);
if (ret)
printk(KERN_ERR "FC Remore Port tgt nexus failed %d\n",
ret);
} }
rport->roles = roles; rport->roles = roles;
......
#include <scsi/scsi_tgt.h>
#ifdef CONFIG_SCSI_FC_TGT_ATTRS
static inline int fc_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id,
char *initiator)
{
return scsi_tgt_it_nexus_create(shost, itn_id, initiator);
}
static inline int fc_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id)
{
return scsi_tgt_it_nexus_destroy(shost, itn_id);
}
#else
static inline int fc_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id,
char *initiator)
{
return 0;
}
static inline int fc_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id)
{
return 0;
}
#endif
...@@ -589,6 +589,10 @@ struct fc_function_template { ...@@ -589,6 +589,10 @@ struct fc_function_template {
int (*vport_disable)(struct fc_vport *, bool); int (*vport_disable)(struct fc_vport *, bool);
int (*vport_delete)(struct fc_vport *); int (*vport_delete)(struct fc_vport *);
/* target-mode drivers' functions */
int (* tsk_mgmt_response)(struct Scsi_Host *, u64, u64, int);
int (* it_nexus_response)(struct Scsi_Host *, u64, int);
/* allocation lengths for host-specific data */ /* allocation lengths for host-specific data */
u32 dd_fcrport_size; u32 dd_fcrport_size;
u32 dd_fcvport_size; u32 dd_fcvport_size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment