[PATCH 5/6 v3] staging: unisys: move parahotplug to sysfs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Move the /proc/visorchipset/parahotplug interface to sysfs under
/sys/devices/platform/visorchipset/parahotplug/deviceenabled and
/sys/devices/platform/visorchipset/parahotplug/devicedisabled.

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.

Moving this interface to sysfs orphans the visorchipset_proc_read_writeonly()
function, so it is also removed.

Signed-off-by: Benjamin Romer <benjamin.romer@xxxxxxxxxx>
---
v3: The interface was split in two, so only the ID need be passed as a parameter
to use the interfaces. Additional documentation was added.
v2: attribute creation was fixed and checks for controlvm_channel pointer were
removed.
 .../unisys/visorchipset/visorchipset_main.c        | 99 +++++++++-------------
 1 file changed, 39 insertions(+), 60 deletions(-)

diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c
index 13f4da8..7a7f515 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset_main.c
+++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c
@@ -98,19 +98,11 @@ static CONTROLVM_MESSAGE_PACKET g_DeviceChangeStatePacket;
 #define is_diagpool_channel(channel_type_guid) \
 	 (uuid_le_cmp(channel_type_guid, UltraDiagPoolChannelProtocolGuid) == 0)
 
-#define VISORCHIPSET_PARAHOTPLUG_PROC_ENTRY_FN "parahotplug"
-static struct proc_dir_entry *parahotplug_proc_dir;
-
 static LIST_HEAD(BusInfoList);
 static LIST_HEAD(DevInfoList);
 
-static struct proc_dir_entry *ProcDir;
 static VISORCHANNEL *ControlVm_channel;
 
-static ssize_t visorchipset_proc_read_writeonly(struct file *file,
-						char __user *buf,
-						size_t len, loff_t *offset);
-
 typedef struct {
 	U8 __iomem *ptr;	/* pointer to base address of payload pool */
 	U64 offset;		/* offset from beginning of controlvm
@@ -293,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,
@@ -317,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
 };
 
@@ -1723,53 +1735,36 @@ parahotplug_process_message(CONTROLVM_MESSAGE *inmsg)
 	}
 }
 
-/*
- * Gets called when the udev script writes to
- * /proc/visorchipset/parahotplug.  Expects input in the form of "<id>
- * <active>" where <id> is the identifier passed to the script that
- * matches a request on the request list, and <active> is 0 or 1
- * indicating whether the device is now enabled or not.
+/* 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
-parahotplug_proc_write(struct file *file, const char __user *buffer,
-		       size_t count, loff_t *ppos)
+ssize_t devicedisabled_store(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
 {
-	char buf[64];
 	uint id;
-	ushort active;
 
-	if (count > sizeof(buf) - 1) {
-		LOGERR("parahotplug_proc_write: count (%d) exceeds size of buffer (%d)",
-		     (int) count, (int) sizeof(buf));
+	if (kstrtouint(buf, 10, &id) != 1)
 		return -EINVAL;
-	}
-	if (copy_from_user(buf, buffer, count)) {
-		LOGERR("parahotplug_proc_write: copy_from_user failed");
-		return -EFAULT;
-	}
-	buf[count] = '\0';
+	parahotplug_request_complete((int) id, 0);
+	return count;
+}
 
-	if (sscanf(buf, "%u %hu", &id, &active) != 2) {
-		id = 0;
-		active = 0;
-	}
+/* 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.
+ */
+ssize_t deviceenabled_store(struct device *dev, struct device_attribute *attr,
+		const char *buf, size_t count)
+{
+	uint id;
 
-	if (active != 1 && active != 0) {
-		LOGERR("parahotplug_proc_write: invalid active field");
+	if (kstrtouint(buf, 10, &id) != 1)
 		return -EINVAL;
-	}
-
-	parahotplug_request_complete((int) id, (U16) active);
-
+	parahotplug_request_complete((int) id, 1);
 	return count;
 }
 
-static const struct file_operations parahotplug_proc_fops = {
-	.owner = THIS_MODULE,
-	.read = visorchipset_proc_read_writeonly,
-	.write = parahotplug_proc_write,
-};
-
 /* Process a controlvm message.
  * Return result:
  *    FALSE - this function will return FALSE only in the case where the
@@ -2312,13 +2307,6 @@ static ssize_t chipsetready_store(struct device *dev,
 	return count;
 }
 
-static ssize_t
-visorchipset_proc_read_writeonly(struct file *file, char __user *buf,
-				 size_t len, loff_t *offset)
-{
-	return 0;
-}
-
 static int __init
 visorchipset_init(void)
 {
@@ -2392,9 +2380,6 @@ visorchipset_init(void)
 
 	memset(&g_ChipSetMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
 
-	parahotplug_proc_dir =
-	    proc_create(VISORCHIPSET_PARAHOTPLUG_PROC_ENTRY_FN, 0200,
-			ProcDir, &parahotplug_proc_fops);
 	memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
 
 	Putfile_buffer_list_pool =
@@ -2487,12 +2472,6 @@ visorchipset_exit(void)
 
 	memset(&g_ChipSetMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
 
-	if (parahotplug_proc_dir) {
-		remove_proc_entry(VISORCHIPSET_PARAHOTPLUG_PROC_ENTRY_FN,
-				  ProcDir);
-		parahotplug_proc_dir = NULL;
-	}
-
 	memset(&g_DelDumpMsgHdr, 0, sizeof(CONTROLVM_MESSAGE_HEADER));
 
 	LOGINF("Channel %s (ControlVm) disconnected",
-- 
1.9.1

_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux