diff options
-rw-r--r-- | drivers/scsi/scsi_transport_sas.c | 36 |
1 files changed, 31 insertions, 5 deletions
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index fed39abeff86..434f3954aa87 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c | |||
@@ -273,7 +273,7 @@ show_sas_phy_##field(struct class_device *cdev, char *buf) \ | |||
273 | if (!phy->local_attached) \ | 273 | if (!phy->local_attached) \ |
274 | return -EINVAL; \ | 274 | return -EINVAL; \ |
275 | \ | 275 | \ |
276 | error = i->f->get_linkerrors(phy); \ | 276 | error = i->f->get_linkerrors ? i->f->get_linkerrors(phy) : 0; \ |
277 | if (error) \ | 277 | if (error) \ |
278 | return error; \ | 278 | return error; \ |
279 | return snprintf(buf, 20, "%u\n", phy->field); \ | 279 | return snprintf(buf, 20, "%u\n", phy->field); \ |
@@ -814,6 +814,14 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
814 | i->rphy_attrs[count] = &i->private_rphy_attrs[count]; \ | 814 | i->rphy_attrs[count] = &i->private_rphy_attrs[count]; \ |
815 | count++ | 815 | count++ |
816 | 816 | ||
817 | #define SETUP_OPTIONAL_RPORT_ATTRIBUTE(field, func) \ | ||
818 | i->private_rphy_attrs[count] = class_device_attr_##field; \ | ||
819 | i->private_rphy_attrs[count].attr.mode = S_IRUGO; \ | ||
820 | i->private_rphy_attrs[count].store = NULL; \ | ||
821 | i->rphy_attrs[count] = &i->private_rphy_attrs[count]; \ | ||
822 | if (i->f->func) \ | ||
823 | count++ | ||
824 | |||
817 | #define SETUP_PORT_ATTRIBUTE(field) \ | 825 | #define SETUP_PORT_ATTRIBUTE(field) \ |
818 | i->private_phy_attrs[count] = class_device_attr_##field; \ | 826 | i->private_phy_attrs[count] = class_device_attr_##field; \ |
819 | i->private_phy_attrs[count].attr.mode = S_IRUGO; \ | 827 | i->private_phy_attrs[count].attr.mode = S_IRUGO; \ |
@@ -821,6 +829,14 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
821 | i->phy_attrs[count] = &i->private_phy_attrs[count]; \ | 829 | i->phy_attrs[count] = &i->private_phy_attrs[count]; \ |
822 | count++ | 830 | count++ |
823 | 831 | ||
832 | #define SETUP_OPTIONAL_PORT_ATTRIBUTE(field, func) \ | ||
833 | i->private_phy_attrs[count] = class_device_attr_##field; \ | ||
834 | i->private_phy_attrs[count].attr.mode = S_IRUGO; \ | ||
835 | i->private_phy_attrs[count].store = NULL; \ | ||
836 | i->phy_attrs[count] = &i->private_phy_attrs[count]; \ | ||
837 | if (i->f->func) \ | ||
838 | count++ | ||
839 | |||
824 | #define SETUP_PORT_ATTRIBUTE_WRONLY(field) \ | 840 | #define SETUP_PORT_ATTRIBUTE_WRONLY(field) \ |
825 | i->private_phy_attrs[count] = class_device_attr_##field; \ | 841 | i->private_phy_attrs[count] = class_device_attr_##field; \ |
826 | i->private_phy_attrs[count].attr.mode = S_IWUGO; \ | 842 | i->private_phy_attrs[count].attr.mode = S_IWUGO; \ |
@@ -828,6 +844,14 @@ static int sas_user_scan(struct Scsi_Host *shost, uint channel, | |||
828 | i->phy_attrs[count] = &i->private_phy_attrs[count]; \ | 844 | i->phy_attrs[count] = &i->private_phy_attrs[count]; \ |
829 | count++ | 845 | count++ |
830 | 846 | ||
847 | #define SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(field, func) \ | ||
848 | i->private_phy_attrs[count] = class_device_attr_##field; \ | ||
849 | i->private_phy_attrs[count].attr.mode = S_IWUGO; \ | ||
850 | i->private_phy_attrs[count].show = NULL; \ | ||
851 | i->phy_attrs[count] = &i->private_phy_attrs[count]; \ | ||
852 | if (i->f->func) \ | ||
853 | count++ | ||
854 | |||
831 | 855 | ||
832 | /** | 856 | /** |
833 | * sas_attach_transport -- instantiate SAS transport template | 857 | * sas_attach_transport -- instantiate SAS transport template |
@@ -883,8 +907,8 @@ sas_attach_transport(struct sas_function_template *ft) | |||
883 | SETUP_PORT_ATTRIBUTE(running_disparity_error_count); | 907 | SETUP_PORT_ATTRIBUTE(running_disparity_error_count); |
884 | SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count); | 908 | SETUP_PORT_ATTRIBUTE(loss_of_dword_sync_count); |
885 | SETUP_PORT_ATTRIBUTE(phy_reset_problem_count); | 909 | SETUP_PORT_ATTRIBUTE(phy_reset_problem_count); |
886 | SETUP_PORT_ATTRIBUTE_WRONLY(link_reset); | 910 | SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(link_reset, phy_reset); |
887 | SETUP_PORT_ATTRIBUTE_WRONLY(hard_reset); | 911 | SETUP_OPTIONAL_PORT_ATTRIBUTE_WRONLY(hard_reset, phy_reset); |
888 | i->phy_attrs[count] = NULL; | 912 | i->phy_attrs[count] = NULL; |
889 | 913 | ||
890 | count = 0; | 914 | count = 0; |
@@ -893,8 +917,10 @@ sas_attach_transport(struct sas_function_template *ft) | |||
893 | SETUP_RPORT_ATTRIBUTE(rphy_device_type); | 917 | SETUP_RPORT_ATTRIBUTE(rphy_device_type); |
894 | SETUP_RPORT_ATTRIBUTE(rphy_sas_address); | 918 | SETUP_RPORT_ATTRIBUTE(rphy_sas_address); |
895 | SETUP_RPORT_ATTRIBUTE(rphy_phy_identifier); | 919 | SETUP_RPORT_ATTRIBUTE(rphy_phy_identifier); |
896 | SETUP_RPORT_ATTRIBUTE(rphy_enclosure_identifier); | 920 | SETUP_OPTIONAL_RPORT_ATTRIBUTE(rphy_enclosure_identifier, |
897 | SETUP_RPORT_ATTRIBUTE(rphy_bay_identifier); | 921 | get_enclosure_identifier); |
922 | SETUP_OPTIONAL_RPORT_ATTRIBUTE(rphy_bay_identifier, | ||
923 | get_bay_identifier); | ||
898 | i->rphy_attrs[count] = NULL; | 924 | i->rphy_attrs[count] = NULL; |
899 | 925 | ||
900 | return &i->t; | 926 | return &i->t; |