X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fscsi%2Fscsi_transport_srp.c;h=8a7af951d98adfd0adcbd63f453837133981e171;hb=d02aacff4467806ee56f147ac8eff6911d95811a;hp=608abd8aef20a2282ccdc840e032cff5ed94043d;hpb=aebd5e476ecc8ceb53577b20f2a352ff4ceffd8d;p=linux-2.6 diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c index 608abd8aef..8a7af951d9 100644 --- a/drivers/scsi/scsi_transport_srp.c +++ b/drivers/scsi/scsi_transport_srp.c @@ -30,6 +30,7 @@ #include #include #include +#include "scsi_transport_srp_internal.h" struct srp_host_attrs { atomic_t next_port_id; @@ -43,20 +44,20 @@ struct srp_internal { struct scsi_transport_template t; struct srp_function_template *f; - struct class_device_attribute *host_attrs[SRP_HOST_ATTRS + 1]; + struct device_attribute *host_attrs[SRP_HOST_ATTRS + 1]; - struct class_device_attribute *rport_attrs[SRP_RPORT_ATTRS + 1]; - struct class_device_attribute private_rport_attrs[SRP_RPORT_ATTRS]; + struct device_attribute *rport_attrs[SRP_RPORT_ATTRS + 1]; + struct device_attribute private_rport_attrs[SRP_RPORT_ATTRS]; struct transport_container rport_attr_cont; }; #define to_srp_internal(tmpl) container_of(tmpl, struct srp_internal, t) #define dev_to_rport(d) container_of(d, struct srp_rport, dev) -#define transport_class_to_srp_rport(cdev) dev_to_rport((cdev)->dev) +#define transport_class_to_srp_rport(dev) dev_to_rport((dev)->parent) static int srp_host_setup(struct transport_container *tc, struct device *dev, - struct class_device *cdev) + struct device *cdev) { struct Scsi_Host *shost = dev_to_shost(dev); struct srp_host_attrs *srp_host = to_srp_host_attrs(shost); @@ -72,7 +73,7 @@ static DECLARE_TRANSPORT_CLASS(srp_rport_class, "srp_remote_ports", NULL, NULL, NULL); #define SETUP_TEMPLATE(attrb, field, perm, test, ro_test, ro_perm) \ - i->private_##attrb[count] = class_device_attr_##field; \ + i->private_##attrb[count] = dev_attr_##field; \ i->private_##attrb[count].attr.mode = perm; \ if (ro_test) { \ i->private_##attrb[count].attr.mode = ro_perm; \ @@ -99,13 +100,14 @@ static DECLARE_TRANSPORT_CLASS(srp_rport_class, "srp_remote_ports", "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" static ssize_t -show_srp_rport_id(struct class_device *cdev, char *buf) +show_srp_rport_id(struct device *dev, struct device_attribute *attr, + char *buf) { - struct srp_rport *rport = transport_class_to_srp_rport(cdev); + struct srp_rport *rport = transport_class_to_srp_rport(dev); return sprintf(buf, SRP_PID_FMT "\n", SRP_PID(rport)); } -static CLASS_DEVICE_ATTR(port_id, S_IRUGO, show_srp_rport_id, NULL); +static DEVICE_ATTR(port_id, S_IRUGO, show_srp_rport_id, NULL); static const struct { u32 value; @@ -116,9 +118,10 @@ static const struct { }; static ssize_t -show_srp_rport_roles(struct class_device *cdev, char *buf) +show_srp_rport_roles(struct device *dev, struct device_attribute *attr, + char *buf) { - struct srp_rport *rport = transport_class_to_srp_rport(cdev); + struct srp_rport *rport = transport_class_to_srp_rport(dev); int i; char *name = NULL; @@ -130,7 +133,7 @@ show_srp_rport_roles(struct class_device *cdev, char *buf) return sprintf(buf, "%s\n", name ? : "unknown"); } -static CLASS_DEVICE_ATTR(roles, S_IRUGO, show_srp_rport_roles, NULL); +static DEVICE_ATTR(roles, S_IRUGO, show_srp_rport_roles, NULL); static void srp_rport_release(struct device *dev) { @@ -184,11 +187,10 @@ static int srp_host_match(struct attribute_container *cont, struct device *dev) /** * srp_rport_add - add a SRP remote port to the device hierarchy - * * @shost: scsi host the remote port is connected to. * @ids: The port id for the remote port. * - * publishes a port to the rest of the system + * Publishes a port to the rest of the system. */ struct srp_rport *srp_rport_add(struct Scsi_Host *shost, struct srp_rport_identifiers *ids) @@ -221,6 +223,18 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost, return ERR_PTR(ret); } + if (shost->active_mode & MODE_TARGET && + ids->roles == SRP_RPORT_ROLE_INITIATOR) { + ret = srp_tgt_it_nexus_create(shost, (unsigned long)rport, + rport->port_id); + if (ret) { + device_del(&rport->dev); + transport_destroy_device(&rport->dev); + put_device(&rport->dev); + return ERR_PTR(ret); + } + } + transport_add_device(&rport->dev); transport_configure_device(&rport->dev); @@ -229,14 +243,19 @@ struct srp_rport *srp_rport_add(struct Scsi_Host *shost, EXPORT_SYMBOL_GPL(srp_rport_add); /** - * srp_rport_del -- remove a SRP remote port - * @port: SRP remote port to remove + * srp_rport_del - remove a SRP remote port + * @rport: SRP remote port to remove * * Removes the specified SRP remote port. */ void srp_rport_del(struct srp_rport *rport) { struct device *dev = &rport->dev; + struct Scsi_Host *shost = dev_to_shost(dev->parent); + + if (shost->active_mode & MODE_TARGET && + rport->roles == SRP_RPORT_ROLE_INITIATOR) + srp_tgt_it_nexus_destroy(shost, (unsigned long)rport); transport_remove_device(dev); device_del(dev); @@ -247,12 +266,13 @@ EXPORT_SYMBOL_GPL(srp_rport_del); static int do_srp_rport_del(struct device *dev, void *data) { - srp_rport_del(dev_to_rport(dev)); + if (scsi_is_srp_rport(dev)) + srp_rport_del(dev_to_rport(dev)); return 0; } /** - * srp_remove_host -- tear down a Scsi_Host's SRP data structures + * srp_remove_host - tear down a Scsi_Host's SRP data structures * @shost: Scsi Host that is torn down * * Removes all SRP remote ports for a given Scsi_Host. @@ -264,8 +284,21 @@ void srp_remove_host(struct Scsi_Host *shost) } EXPORT_SYMBOL_GPL(srp_remove_host); +static int srp_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id, + int result) +{ + struct srp_internal *i = to_srp_internal(shost->transportt); + return i->f->tsk_mgmt_response(shost, nexus, tm_id, result); +} + +static int srp_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result) +{ + struct srp_internal *i = to_srp_internal(shost->transportt); + return i->f->it_nexus_response(shost, nexus, result); +} + /** - * srp_attach_transport -- instantiate SRP transport template + * srp_attach_transport - instantiate SRP transport template * @ft: SRP transport class function template */ struct scsi_transport_template * @@ -278,6 +311,9 @@ srp_attach_transport(struct srp_function_template *ft) if (!i) return NULL; + i->t.tsk_mgmt_response = srp_tsk_mgmt_response; + i->t.it_nexus_response = srp_it_nexus_response; + i->t.host_size = sizeof(struct srp_host_attrs); i->t.host_attrs.ac.attrs = &i->host_attrs[0]; i->t.host_attrs.ac.class = &srp_host_class.class; @@ -302,7 +338,7 @@ srp_attach_transport(struct srp_function_template *ft) EXPORT_SYMBOL_GPL(srp_attach_transport); /** - * srp_release_transport -- release SRP transport template instance + * srp_release_transport - release SRP transport template instance * @t: transport template instance */ void srp_release_transport(struct scsi_transport_template *t)