]> err.no Git - linux-2.6/commitdiff
[SCSI] sas: add support for PHY resets
authorChristoph Hellwig <hch@lst.de>
Wed, 19 Oct 2005 18:01:31 +0000 (20:01 +0200)
committerJames Bottomley <jejb@mulgrave.(none)>
Sat, 29 Oct 2005 00:08:03 +0000 (19:08 -0500)
Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
drivers/scsi/scsi_transport_sas.c
include/scsi/scsi_transport_sas.h

index f5618c1116f43f8d122a95def3322e3f86c5f4b7..0cc766a9aa6585a5ffef2292b355478cd31b4235 100644 (file)
@@ -34,7 +34,7 @@
 
 
 #define SAS_HOST_ATTRS         0
-#define SAS_PORT_ATTRS         15
+#define SAS_PORT_ATTRS         17
 #define SAS_RPORT_ATTRS                5
 
 struct sas_internal {
@@ -289,9 +289,39 @@ show_sas_device_type(struct class_device *cdev, char *buf)
                return snprintf(buf, 20, "none\n");
        return get_sas_device_type_names(phy->identify.device_type, buf);
 }
-
 static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL);
 
+static ssize_t do_sas_phy_reset(struct class_device *cdev,
+               size_t count, int hard_reset)
+{
+       struct sas_phy *phy = transport_class_to_phy(cdev);
+       struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+       struct sas_internal *i = to_sas_internal(shost->transportt);
+       int error;
+
+       if (!phy->local_attached)
+               return -EINVAL;
+
+       error = i->f->phy_reset(phy, hard_reset);
+       if (error)
+               return error;
+       return count;
+};
+
+static ssize_t store_sas_link_reset(struct class_device *cdev,
+               const char *buf, size_t count)
+{
+       return do_sas_phy_reset(cdev, count, 0);
+}
+static CLASS_DEVICE_ATTR(link_reset, S_IWUSR, NULL, store_sas_link_reset);
+
+static ssize_t store_sas_hard_reset(struct class_device *cdev,
+               const char *buf, size_t count)
+{
+       return do_sas_phy_reset(cdev, count, 1);
+}
+static CLASS_DEVICE_ATTR(hard_reset, S_IWUSR, NULL, store_sas_hard_reset);
+
 sas_phy_protocol_attr(identify.initiator_port_protocols,
                initiator_port_protocols);
 sas_phy_protocol_attr(identify.target_port_protocols,
@@ -725,6 +755,13 @@ static struct device *sas_target_parent(struct Scsi_Host *shost,
         i->phy_attrs[count] = &i->private_phy_attrs[count];            \
        count++
 
+#define SETUP_PORT_ATTRIBUTE_WRONLY(field)                             \
+       i->private_phy_attrs[count] = class_device_attr_##field;        \
+       i->private_phy_attrs[count].attr.mode = S_IWUGO;                \
+       i->private_phy_attrs[count].show = NULL;                        \
+       i->phy_attrs[count] = &i->private_phy_attrs[count];             \
+       count++
+
 
 /**
  * sas_attach_transport  --  instantiate SAS transport template
@@ -781,6 +818,8 @@ sas_attach_transport(struct sas_function_template *ft)
        SETUP_PORT_ATTRIBUTE(running_disparity_error_count);
        SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count);
        SETUP_PORT_ATTRIBUTE(phy_reset_problem_count);
+       SETUP_PORT_ATTRIBUTE_WRONLY(link_reset);
+       SETUP_PORT_ATTRIBUTE_WRONLY(hard_reset);
        i->phy_attrs[count] = NULL;
 
        count = 0;
index 57eb68c6e9a796450f3c9549bc033601f9da09d9..b91400bfb02a430fc1c0186ac2281237f36860b1 100644 (file)
@@ -94,6 +94,7 @@ struct sas_rphy {
 /* The functions by which the transport class and the driver communicate */
 struct sas_function_template {
        int (*get_linkerrors)(struct sas_phy *);
+       int (*phy_reset)(struct sas_phy *, int);
 };