staging: unisys: add sysfs entries for parahotplug support
authorBenjamin Romer <benjamin.romer@unisys.com>
Tue, 29 Jul 2014 15:11:21 +0000 (11:11 -0400)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 31 Jul 2014 00:09:53 +0000 (17:09 -0700)
This patch adds new a new directory parahotplug to the visorchipset sysfs
directory, and two new attributes, deviceenabled, and devicedisabled, into the
new directory, to add s-Par parahotplug support.

The parahotplug interface is used to deal with SR-IOV recovery situations on
s-Par guest partitions. The command service partition will send a message to a
guest when an SR-IOV device that guest is using needs to be temporarily removed.
The message triggers a udev event that will cause a recovery script to run.
When that script has completed its work, it will write to one of the
parahotplug interfaces to send a message back to Command, indicating that the
recovery action has completed.

When a guest that is sharing an SR-IOV device is restarted, that guest will
take down the PF driver on the device, but any guests with VFs will not know
that their device needs to be reset as well. The recovery script makes it so
the device will be shut down fully and then restarted after the sharing guest
comes back up, and ensures that the timing is correct.

Signed-off-by: Benjamin Romer <benjamin.romer@unisys.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/unisys/visorchipset/visorchipset_main.c

index 34b28d6b7410eb0186ebcc8439d9b8b3f00c756a..858f5c5c19d087f95b52596b5d41abb78228378a 100644 (file)
@@ -285,6 +285,14 @@ static ssize_t chipsetready_store(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count);
 static DEVICE_ATTR_WO(chipsetready);
 
+static ssize_t devicedisabled_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count);
+static DEVICE_ATTR_WO(devicedisabled);
+
+static ssize_t deviceenabled_store(struct device *dev,
+               struct device_attribute *attr, const char *buf, size_t count);
+static DEVICE_ATTR_WO(deviceenabled);
+
 static struct attribute *visorchipset_install_attrs[] = {
        &dev_attr_toolaction.attr,
        &dev_attr_boottotool.attr,
@@ -309,9 +317,21 @@ static struct attribute_group visorchipset_guest_group = {
        .attrs = visorchipset_guest_attrs
 };
 
+static struct attribute *visorchipset_parahotplug_attrs[] = {
+       &dev_attr_devicedisabled.attr,
+       &dev_attr_deviceenabled.attr,
+       NULL
+};
+
+static struct attribute_group visorchipset_parahotplug_group = {
+       .name = "parahotplug",
+       .attrs = visorchipset_parahotplug_attrs
+};
+
 static const struct attribute_group *visorchipset_dev_groups[] = {
        &visorchipset_install_group,
        &visorchipset_guest_group,
+       &visorchipset_parahotplug_group,
        NULL
 };
 
@@ -2270,6 +2290,38 @@ static ssize_t chipsetready_store(struct device *dev,
                return -EINVAL;
 }
 
+/* The parahotplug/devicedisabled interface gets called by our support script
+ * when an SR-IOV device has been shut down. The ID is passed to the script
+ * and then passed back when the device has been removed.
+ */
+static ssize_t devicedisabled_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       uint id;
+
+       if (kstrtouint(buf, 10, &id) != 0)
+               return -EINVAL;
+
+       parahotplug_request_complete(id, 0);
+       return count;
+}
+
+/* The parahotplug/deviceenabled interface gets called by our support script
+ * when an SR-IOV device has been recovered. The ID is passed to the script
+ * and then passed back when the device has been brought back up.
+ */
+static ssize_t deviceenabled_store(struct device *dev,
+       struct device_attribute *attr, const char *buf, size_t count)
+{
+       uint id;
+
+       if (kstrtouint(buf, 10, &id) != 0)
+               return -EINVAL;
+
+       parahotplug_request_complete(id, 1);
+       return count;
+}
+
 static int __init
 visorchipset_init(void)
 {