+static struct attribute *host_attributes[] = {
+ &dev_attr_signalling.attr,
+ NULL
+};
+
+static struct attribute_group host_attribute_group = {
+ .attrs = host_attributes,
+};
+
+static int spi_host_configure(struct transport_container *tc,
+ struct device *dev,
+ struct device *cdev)
+{
+ struct kobject *kobj = &cdev->kobj;
+ struct Scsi_Host *shost = transport_class_to_shost(cdev);
+ struct spi_internal *si = to_spi_internal(shost->transportt);
+ struct attribute *attr = &dev_attr_signalling.attr;
+ int rc = 0;
+
+ if (si->f->set_signalling)
+ rc = sysfs_chmod_file(kobj, attr, attr->mode | S_IWUSR);
+
+ return rc;
+}
+
+/* returns true if we should be showing the variable. Also
+ * overloads the return by setting 1<<1 if the attribute should
+ * be writeable */
+#define TARGET_ATTRIBUTE_HELPER(name) \
+ (si->f->show_##name ? S_IRUGO : 0) | \
+ (si->f->set_##name ? S_IWUSR : 0)
+
+static mode_t target_attribute_is_visible(struct kobject *kobj,
+ struct attribute *attr, int i)
+{
+ struct device *cdev = container_of(kobj, struct device, kobj);
+ struct scsi_target *starget = transport_class_to_starget(cdev);
+ struct Scsi_Host *shost = transport_class_to_shost(cdev);
+ struct spi_internal *si = to_spi_internal(shost->transportt);
+
+ if (attr == &dev_attr_period.attr &&
+ spi_support_sync(starget))
+ return TARGET_ATTRIBUTE_HELPER(period);
+ else if (attr == &dev_attr_min_period.attr &&
+ spi_support_sync(starget))
+ return TARGET_ATTRIBUTE_HELPER(period);
+ else if (attr == &dev_attr_offset.attr &&
+ spi_support_sync(starget))
+ return TARGET_ATTRIBUTE_HELPER(offset);
+ else if (attr == &dev_attr_max_offset.attr &&
+ spi_support_sync(starget))
+ return TARGET_ATTRIBUTE_HELPER(offset);
+ else if (attr == &dev_attr_width.attr &&
+ spi_support_wide(starget))
+ return TARGET_ATTRIBUTE_HELPER(width);
+ else if (attr == &dev_attr_max_width.attr &&
+ spi_support_wide(starget))
+ return TARGET_ATTRIBUTE_HELPER(width);
+ else if (attr == &dev_attr_iu.attr &&
+ spi_support_ius(starget))
+ return TARGET_ATTRIBUTE_HELPER(iu);
+ else if (attr == &dev_attr_dt.attr &&
+ spi_support_dt(starget))
+ return TARGET_ATTRIBUTE_HELPER(dt);
+ else if (attr == &dev_attr_qas.attr &&
+ spi_support_qas(starget))
+ return TARGET_ATTRIBUTE_HELPER(qas);
+ else if (attr == &dev_attr_wr_flow.attr &&
+ spi_support_ius(starget))
+ return TARGET_ATTRIBUTE_HELPER(wr_flow);
+ else if (attr == &dev_attr_rd_strm.attr &&
+ spi_support_ius(starget))
+ return TARGET_ATTRIBUTE_HELPER(rd_strm);
+ else if (attr == &dev_attr_rti.attr &&
+ spi_support_ius(starget))
+ return TARGET_ATTRIBUTE_HELPER(rti);
+ else if (attr == &dev_attr_pcomp_en.attr &&
+ spi_support_ius(starget))
+ return TARGET_ATTRIBUTE_HELPER(pcomp_en);
+ else if (attr == &dev_attr_hold_mcs.attr &&
+ spi_support_ius(starget))
+ return TARGET_ATTRIBUTE_HELPER(hold_mcs);
+ else if (attr == &dev_attr_revalidate.attr)
+ return S_IWUSR;
+
+ return 0;
+}
+
+static struct attribute *target_attributes[] = {
+ &dev_attr_period.attr,
+ &dev_attr_min_period.attr,
+ &dev_attr_offset.attr,
+ &dev_attr_max_offset.attr,
+ &dev_attr_width.attr,
+ &dev_attr_max_width.attr,
+ &dev_attr_iu.attr,
+ &dev_attr_dt.attr,
+ &dev_attr_qas.attr,
+ &dev_attr_wr_flow.attr,
+ &dev_attr_rd_strm.attr,
+ &dev_attr_rti.attr,
+ &dev_attr_pcomp_en.attr,
+ &dev_attr_hold_mcs.attr,
+ &dev_attr_revalidate.attr,
+ NULL
+};
+
+static struct attribute_group target_attribute_group = {
+ .attrs = target_attributes,
+ .is_visible = target_attribute_is_visible,
+};
+
+static int spi_target_configure(struct transport_container *tc,
+ struct device *dev,
+ struct device *cdev)
+{
+ struct kobject *kobj = &cdev->kobj;
+
+ /* force an update based on parameters read from the device */
+ sysfs_update_group(kobj, &target_attribute_group);
+
+ return 0;
+}
+