aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/scsi_transport_sas.c43
-rw-r--r--include/scsi/scsi_transport_sas.h1
2 files changed, 42 insertions, 2 deletions
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index f5618c1116f4..0cc766a9aa65 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -34,7 +34,7 @@
34 34
35 35
36#define SAS_HOST_ATTRS 0 36#define SAS_HOST_ATTRS 0
37#define SAS_PORT_ATTRS 15 37#define SAS_PORT_ATTRS 17
38#define SAS_RPORT_ATTRS 5 38#define SAS_RPORT_ATTRS 5
39 39
40struct sas_internal { 40struct sas_internal {
@@ -289,9 +289,39 @@ show_sas_device_type(struct class_device *cdev, char *buf)
289 return snprintf(buf, 20, "none\n"); 289 return snprintf(buf, 20, "none\n");
290 return get_sas_device_type_names(phy->identify.device_type, buf); 290 return get_sas_device_type_names(phy->identify.device_type, buf);
291} 291}
292
293static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL); 292static CLASS_DEVICE_ATTR(device_type, S_IRUGO, show_sas_device_type, NULL);
294 293
294static ssize_t do_sas_phy_reset(struct class_device *cdev,
295 size_t count, int hard_reset)
296{
297 struct sas_phy *phy = transport_class_to_phy(cdev);
298 struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
299 struct sas_internal *i = to_sas_internal(shost->transportt);
300 int error;
301
302 if (!phy->local_attached)
303 return -EINVAL;
304
305 error = i->f->phy_reset(phy, hard_reset);
306 if (error)
307 return error;
308 return count;
309};
310
311static ssize_t store_sas_link_reset(struct class_device *cdev,
312 const char *buf, size_t count)
313{
314 return do_sas_phy_reset(cdev, count, 0);
315}
316static CLASS_DEVICE_ATTR(link_reset, S_IWUSR, NULL, store_sas_link_reset);
317
318static ssize_t store_sas_hard_reset(struct class_device *cdev,
319 const char *buf, size_t count)
320{
321 return do_sas_phy_reset(cdev, count, 1);
322}
323static CLASS_DEVICE_ATTR(hard_reset, S_IWUSR, NULL, store_sas_hard_reset);
324
295sas_phy_protocol_attr(identify.initiator_port_protocols, 325sas_phy_protocol_attr(identify.initiator_port_protocols,
296 initiator_port_protocols); 326 initiator_port_protocols);
297sas_phy_protocol_attr(identify.target_port_protocols, 327sas_phy_protocol_attr(identify.target_port_protocols,
@@ -725,6 +755,13 @@ static struct device *sas_target_parent(struct Scsi_Host *shost,
725 i->phy_attrs[count] = &i->private_phy_attrs[count]; \ 755 i->phy_attrs[count] = &i->private_phy_attrs[count]; \
726 count++ 756 count++
727 757
758#define SETUP_PORT_ATTRIBUTE_WRONLY(field) \
759 i->private_phy_attrs[count] = class_device_attr_##field; \
760 i->private_phy_attrs[count].attr.mode = S_IWUGO; \
761 i->private_phy_attrs[count].show = NULL; \
762 i->phy_attrs[count] = &i->private_phy_attrs[count]; \
763 count++
764
728 765
729/** 766/**
730 * sas_attach_transport -- instantiate SAS transport template 767 * sas_attach_transport -- instantiate SAS transport template
@@ -781,6 +818,8 @@ sas_attach_transport(struct sas_function_template *ft)
781 SETUP_PORT_ATTRIBUTE(running_disparity_error_count); 818 SETUP_PORT_ATTRIBUTE(running_disparity_error_count);
782 SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count); 819 SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count);
783 SETUP_PORT_ATTRIBUTE(phy_reset_problem_count); 820 SETUP_PORT_ATTRIBUTE(phy_reset_problem_count);
821 SETUP_PORT_ATTRIBUTE_WRONLY(link_reset);
822 SETUP_PORT_ATTRIBUTE_WRONLY(hard_reset);
784 i->phy_attrs[count] = NULL; 823 i->phy_attrs[count] = NULL;
785 824
786 count = 0; 825 count = 0;
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h
index 57eb68c6e9a7..b91400bfb02a 100644
--- a/include/scsi/scsi_transport_sas.h
+++ b/include/scsi/scsi_transport_sas.h
@@ -94,6 +94,7 @@ struct sas_rphy {
94/* The functions by which the transport class and the driver communicate */ 94/* The functions by which the transport class and the driver communicate */
95struct sas_function_template { 95struct sas_function_template {
96 int (*get_linkerrors)(struct sas_phy *); 96 int (*get_linkerrors)(struct sas_phy *);
97 int (*phy_reset)(struct sas_phy *, int);
97}; 98};
98 99
99 100