aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2011-09-16 14:41:13 -0400
committerRoland Dreier <roland@purestorage.com>2012-11-30 20:40:33 -0500
commitdc1bdbd9b8a077018d82230bc378f1bcfd8adba8 (patch)
treee6484d9d378a0bad8a4f7057ae29d4164b33278e /drivers
parent7e1265bfe75f0ef1a9f5cfde202df68b7e35a53f (diff)
IB/srp: Allow SRP disconnect through sysfs
Make it possible to disconnect the IB RC connection used by the SRP protocol to communicate with a target. Have the SRP transport layer create a sysfs "delete" attribute for initiator drivers that support this functionality. Signed-off-by: Bart Van Assche <bvanassche@acm.org> Acked-by: David Dillow <dillowda@ornl.gov> Cc: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> Cc: Robert Jennings <rcj@linux.vnet.ibm.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c10
-rw-r--r--drivers/scsi/scsi_transport_srp.c22
2 files changed, 31 insertions, 1 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 84d9298ed989..d5088ce78290 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -549,6 +549,13 @@ static void srp_remove_work(struct work_struct *work)
549 srp_remove_target(target); 549 srp_remove_target(target);
550} 550}
551 551
552static void srp_rport_delete(struct srp_rport *rport)
553{
554 struct srp_target_port *target = rport->lld_data;
555
556 srp_queue_remove_work(target);
557}
558
552static int srp_connect_target(struct srp_target_port *target) 559static int srp_connect_target(struct srp_target_port *target)
553{ 560{
554 int retries = 3; 561 int retries = 3;
@@ -1958,6 +1965,8 @@ static int srp_add_target(struct srp_host *host, struct srp_target_port *target)
1958 return PTR_ERR(rport); 1965 return PTR_ERR(rport);
1959 } 1966 }
1960 1967
1968 rport->lld_data = target;
1969
1961 spin_lock(&host->target_lock); 1970 spin_lock(&host->target_lock);
1962 list_add_tail(&target->list, &host->target_list); 1971 list_add_tail(&target->list, &host->target_list);
1963 spin_unlock(&host->target_lock); 1972 spin_unlock(&host->target_lock);
@@ -2524,6 +2533,7 @@ static void srp_remove_one(struct ib_device *device)
2524} 2533}
2525 2534
2526static struct srp_function_template ib_srp_transport_functions = { 2535static struct srp_function_template ib_srp_transport_functions = {
2536 .rport_delete = srp_rport_delete,
2527}; 2537};
2528 2538
2529static int __init srp_init_module(void) 2539static int __init srp_init_module(void)
diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c
index 0d85f797141f..f379c7f3034c 100644
--- a/drivers/scsi/scsi_transport_srp.c
+++ b/drivers/scsi/scsi_transport_srp.c
@@ -38,7 +38,7 @@ struct srp_host_attrs {
38#define to_srp_host_attrs(host) ((struct srp_host_attrs *)(host)->shost_data) 38#define to_srp_host_attrs(host) ((struct srp_host_attrs *)(host)->shost_data)
39 39
40#define SRP_HOST_ATTRS 0 40#define SRP_HOST_ATTRS 0
41#define SRP_RPORT_ATTRS 2 41#define SRP_RPORT_ATTRS 3
42 42
43struct srp_internal { 43struct srp_internal {
44 struct scsi_transport_template t; 44 struct scsi_transport_template t;
@@ -116,6 +116,24 @@ show_srp_rport_roles(struct device *dev, struct device_attribute *attr,
116 116
117static DEVICE_ATTR(roles, S_IRUGO, show_srp_rport_roles, NULL); 117static DEVICE_ATTR(roles, S_IRUGO, show_srp_rport_roles, NULL);
118 118
119static ssize_t store_srp_rport_delete(struct device *dev,
120 struct device_attribute *attr,
121 const char *buf, size_t count)
122{
123 struct srp_rport *rport = transport_class_to_srp_rport(dev);
124 struct Scsi_Host *shost = dev_to_shost(dev);
125 struct srp_internal *i = to_srp_internal(shost->transportt);
126
127 if (i->f->rport_delete) {
128 i->f->rport_delete(rport);
129 return count;
130 } else {
131 return -ENOSYS;
132 }
133}
134
135static DEVICE_ATTR(delete, S_IWUSR, NULL, store_srp_rport_delete);
136
119static void srp_rport_release(struct device *dev) 137static void srp_rport_release(struct device *dev)
120{ 138{
121 struct srp_rport *rport = dev_to_rport(dev); 139 struct srp_rport *rport = dev_to_rport(dev);
@@ -309,6 +327,8 @@ srp_attach_transport(struct srp_function_template *ft)
309 count = 0; 327 count = 0;
310 i->rport_attrs[count++] = &dev_attr_port_id; 328 i->rport_attrs[count++] = &dev_attr_port_id;
311 i->rport_attrs[count++] = &dev_attr_roles; 329 i->rport_attrs[count++] = &dev_attr_roles;
330 if (ft->rport_delete)
331 i->rport_attrs[count++] = &dev_attr_delete;
312 i->rport_attrs[count++] = NULL; 332 i->rport_attrs[count++] = NULL;
313 BUG_ON(count > ARRAY_SIZE(i->rport_attrs)); 333 BUG_ON(count > ARRAY_SIZE(i->rport_attrs));
314 334