[PATCH 105/141] staging: unisys: move hypervisor calls into visorbus

Benjamin Romer benjamin.romer at unisys.com
Tue May 5 22:37:22 UTC 2015


From: David Kershner <david.kershner at unisys.com>

Move hypervisor calls into visorbus and move vbusdeviceinfo.h into
visorbus.
Drivers will call into that to update clientInfo field.

Signed-off-by: David Kershner <david.kershner at unisys.com>
Signed-off-by: Benjamin Romer <benjamin.romer at unisys.com>
---
 .../unisys/common-spar/include/iovmcall_gnuc.h     |  49 -----
 .../unisys/common-spar/include/vbusdeviceinfo.h    | 213 ---------------------
 .../unisys/common-spar/include/vmcallinterface.h   | 163 ----------------
 drivers/staging/unisys/visorbus/iovmcall_gnuc.h    |  49 +++++
 drivers/staging/unisys/visorbus/vbusdeviceinfo.h   | 213 +++++++++++++++++++++
 drivers/staging/unisys/visorbus/vmcallinterface.h  | 161 ++++++++++++++++
 6 files changed, 423 insertions(+), 425 deletions(-)
 delete mode 100644 drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h
 delete mode 100644 drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h
 delete mode 100644 drivers/staging/unisys/common-spar/include/vmcallinterface.h
 create mode 100644 drivers/staging/unisys/visorbus/iovmcall_gnuc.h
 create mode 100644 drivers/staging/unisys/visorbus/vbusdeviceinfo.h
 create mode 100644 drivers/staging/unisys/visorbus/vmcallinterface.h

diff --git a/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h b/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h
deleted file mode 100644
index 57dd93e..0000000
--- a/drivers/staging/unisys/common-spar/include/iovmcall_gnuc.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- */
-
-/* Linux GCC Version (32-bit and 64-bit) */
-static inline unsigned long
-__unisys_vmcall_gnuc(unsigned long tuple, unsigned long reg_ebx,
-		     unsigned long reg_ecx)
-{
-	unsigned long result = 0;
-	unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
-
-	cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
-	if (!(cpuid_ecx & 0x80000000))
-		return -1;
-
-	__asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
-		"a"(tuple), "b"(reg_ebx), "c"(reg_ecx));
-	return result;
-}
-
-static inline unsigned long
-__unisys_extended_vmcall_gnuc(unsigned long long tuple,
-			      unsigned long long reg_ebx,
-			      unsigned long long reg_ecx,
-			      unsigned long long reg_edx)
-{
-	unsigned long result = 0;
-	unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
-
-	cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
-	if (!(cpuid_ecx & 0x80000000))
-		return -1;
-
-	__asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
-		"a"(tuple), "b"(reg_ebx), "c"(reg_ecx), "d"(reg_edx));
-	return result;
-}
diff --git a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h b/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h
deleted file mode 100644
index 9b6d3e6..0000000
--- a/drivers/staging/unisys/common-spar/include/vbusdeviceinfo.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- */
-
-#ifndef __VBUSDEVICEINFO_H__
-#define __VBUSDEVICEINFO_H__
-
-#include <linux/types.h>
-
-#pragma pack(push, 1)		/* both GCC and VC now allow this pragma */
-
-/* An array of this struct is present in the channel area for each vbus.
- * (See vbuschannel.h.)
- * It is filled in by the client side to provide info about the device
- * and driver from the client's perspective.
- */
-struct ultra_vbus_deviceinfo {
-	u8 devtype[16];		/* short string identifying the device type */
-	u8 drvname[16];		/* driver .sys file name */
-	u8 infostrs[96];	/* sequence of tab-delimited id strings: */
-	/* <DRIVER_REV> <DRIVER_VERTAG> <DRIVER_COMPILETIME> */
-	u8 reserved[128];	/* pad size to 256 bytes */
-};
-
-#pragma pack(pop)
-
-/* Reads chars from the buffer at <src> for <srcmax> bytes, and writes to
- * the buffer at <p>, which is <remain> bytes long, ensuring never to
- * overflow the buffer at <p>, using the following rules:
- * - printable characters are simply copied from the buffer at <src> to the
- *   buffer at <p>
- * - intervening streaks of non-printable characters in the buffer at <src>
- *   are replaced with a single space in the buffer at <p>
- * Note that we pay no attention to '\0'-termination.
- * Returns the number of bytes written to <p>.
- *
- * Pass <p> == NULL and <remain> == 0 for this special behavior.  In this
- * case, we simply return the number of bytes that WOULD HAVE been written
- * to a buffer at <p>, had it been infinitely big.
- */
-static inline int
-vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax)
-{
-	int chars = 0;
-	int nonprintable_streak = 0;
-
-	while (srcmax > 0) {
-		if ((*src >= ' ') && (*src < 0x7f)) {
-			if (nonprintable_streak) {
-				if (remain > 0) {
-					*p = ' ';
-					p++;
-					remain--;
-					chars++;
-				} else if (p == NULL) {
-					chars++;
-				}
-				nonprintable_streak = 0;
-			}
-			if (remain > 0) {
-				*p = *src;
-				p++;
-				remain--;
-				chars++;
-			} else if (p == NULL) {
-				chars++;
-			}
-		} else {
-			nonprintable_streak = 1;
-		}
-		src++;
-		srcmax--;
-	}
-	return chars;
-}
-
-#define VBUSCHANNEL_ADDACHAR(ch, p, remain, chars) \
-	do {					   \
-		if (remain <= 0)		   \
-			break;			   \
-		*p = ch;			   \
-		p++;  chars++;  remain--;	   \
-	} while (0)
-
-/* Converts the non-negative value at <num> to an ascii decimal string
- * at <p>, writing at most <remain> bytes.  Note there is NO '\0' termination
- * written to <p>.
- *
- * Returns the number of bytes written to <p>.
- *
- * Note that we create this function because we need to do this operation in
- * an environment-independent way (since we are in a common header file).
- */
-static inline int
-vbuschannel_itoa(char *p, int remain, int num)
-{
-	int digits = 0;
-	char s[32];
-	int i;
-
-	if (num == 0) {
-		/* '0' is a special case */
-		if (remain <= 0)
-			return 0;
-		*p = '0';
-		return 1;
-	}
-	/* form a backwards decimal ascii string in <s> */
-	while (num > 0) {
-		if (digits >= (int)sizeof(s))
-			return 0;
-		s[digits++] = (num % 10) + '0';
-		num = num / 10;
-	}
-	if (remain < digits) {
-		/* not enough room left at <p> to hold number, so fill with
-		 * '?' */
-		for (i = 0; i < remain; i++, p++)
-			*p = '?';
-		return remain;
-	}
-	/* plug in the decimal ascii string representing the number, by */
-	/* reversing the string we just built in <s> */
-	i = digits;
-	while (i > 0) {
-		i--;
-		*p = s[i];
-		p++;
-	}
-	return digits;
-}
-
-/* Reads <devInfo>, and converts its contents to a printable string at <p>,
- * writing at most <remain> bytes.  Note there is NO '\0' termination
- * written to <p>.
- *
- * Pass <devix> >= 0 if you want a device index presented.
- *
- * Returns the number of bytes written to <p>.
- */
-static inline int
-vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo,
-			      char *p, int remain, int devix)
-{
-	char *psrc;
-	int nsrc, x, i, pad;
-	int chars = 0;
-
-	psrc = &devinfo->devtype[0];
-	nsrc = sizeof(devinfo->devtype);
-	if (vbuschannel_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0)
-		return 0;
-
-	/* emit device index */
-	if (devix >= 0) {
-		VBUSCHANNEL_ADDACHAR('[', p, remain, chars);
-		x = vbuschannel_itoa(p, remain, devix);
-		p += x;
-		remain -= x;
-		chars += x;
-		VBUSCHANNEL_ADDACHAR(']', p, remain, chars);
-	} else {
-		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
-		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
-		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
-	}
-
-	/* emit device type */
-	x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
-	p += x;
-	remain -= x;
-	chars += x;
-	pad = 15 - x;		/* pad device type to be exactly 15 chars */
-	for (i = 0; i < pad; i++)
-		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
-	VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
-
-	/* emit driver name */
-	psrc = &devinfo->drvname[0];
-	nsrc = sizeof(devinfo->drvname);
-	x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
-	p += x;
-	remain -= x;
-	chars += x;
-	pad = 15 - x;		/* pad driver name to be exactly 15 chars */
-	for (i = 0; i < pad; i++)
-		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
-	VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
-
-	/* emit strings */
-	psrc = &devinfo->infostrs[0];
-	nsrc = sizeof(devinfo->infostrs);
-	x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
-	p += x;
-	remain -= x;
-	chars += x;
-	VBUSCHANNEL_ADDACHAR('\n', p, remain, chars);
-
-	return chars;
-}
-
-#endif
diff --git a/drivers/staging/unisys/common-spar/include/vmcallinterface.h b/drivers/staging/unisys/common-spar/include/vmcallinterface.h
deleted file mode 100644
index 59a7459..0000000
--- a/drivers/staging/unisys/common-spar/include/vmcallinterface.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or (at
- * your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
- * NON INFRINGEMENT.  See the GNU General Public License for more
- * details.
- */
-
-#ifndef __IOMONINTF_H__
-#define __IOMONINTF_H__
-
-/*
-* This file contains all structures needed to support the VMCALLs for IO
-* Virtualization.  The VMCALLs are provided by Monitor and used by IO code
-* running on IO Partitions.
-*/
-
-#ifdef __GNUC__
-#include "iovmcall_gnuc.h"
-#endif	/*  */
-#include "diagchannel.h"
-
-#ifdef VMCALL_IO_CONTROLVM_ADDR
-#undef VMCALL_IO_CONTROLVM_ADDR
-#endif	/*  */
-
-/* define subsystem number for AppOS, used in uislib driver  */
-#define MDS_APPOS 0x4000000000000000L	/* subsystem = 62 - AppOS */
-enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples  */
-	    /* Note: when a new VMCALL is added:
-	     * - the 1st 2 hex digits correspond to one of the
-	     *   VMCALL_MONITOR_INTERFACE types and
-	     * - the next 2 hex digits are the nth relative instance of within a
-	     *   type
-	     * E.G. for VMCALL_VIRTPART_RECYCLE_PART,
-	     * - the 0x02 identifies it as a VMCALL_VIRTPART type and
-	     * - the 0x01 identifies it as the 1st instance of a VMCALL_VIRTPART
-	     *   type of VMCALL
-	     */
-
-	VMCALL_IO_CONTROLVM_ADDR = 0x0501,	/* used by all Guests, not just
-						 * IO */
-	VMCALL_IO_DIAG_ADDR = 0x0508,
-	VMCALL_IO_VISORSERIAL_ADDR = 0x0509,
-	VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET = 0x0708, /* Allow caller to
-							  * query virtual time
-							  * offset */
-	VMCALL_CHANNEL_VERSION_MISMATCH = 0x0709,
-	VMCALL_POST_CODE_LOGEVENT = 0x070B,	/* LOGEVENT Post Code (RDX) with
-						 * specified subsystem mask (RCX
-						 * - monitor_subsystems.h) and
-						 * severity (RDX) */
-	VMCALL_GENERIC_SURRENDER_QUANTUM_FOREVER = 0x0802, /* Yield the
-							    * remainder & all
-							    * future quantums of
-							    * the caller */
-	VMCALL_MEASUREMENT_DO_NOTHING = 0x0901,
-	VMCALL_UPDATE_PHYSICAL_TIME = 0x0a02	/* Allow
-						 * ULTRA_SERVICE_CAPABILITY_TIME
-						 * capable guest to make
-						 * VMCALL */
-};
-
-#define VMCALL_SUCCESS 0
-#define VMCALL_SUCCESSFUL(result)	(result == 0)
-
-#ifdef __GNUC__
-#define unisys_vmcall(tuple, reg_ebx, reg_ecx) \
-	__unisys_vmcall_gnuc(tuple, reg_ebx, reg_ecx)
-#define unisys_extended_vmcall(tuple, reg_ebx, reg_ecx, reg_edx) \
-	__unisys_extended_vmcall_gnuc(tuple, reg_ebx, reg_ecx, reg_edx)
-#define ISSUE_IO_VMCALL(method, param, result) \
-	(result = unisys_vmcall(method, (param) & 0xFFFFFFFF,	\
-				(param) >> 32))
-#define ISSUE_IO_EXTENDED_VMCALL(method, param1, param2, param3) \
-	unisys_extended_vmcall(method, param1, param2, param3)
-
-    /* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently
-     * not used much */
-#define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity)		\
-do {									\
-	ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity,	\
-				 MDS_APPOS, postcode);			\
-} while (0)
-#endif
-
-/* Structures for IO VMCALLs */
-
-/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
-/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
-#pragma pack(push, 1)
-struct phys_info {
-	u64 pi_pfn;
-	u16 pi_off;
-	u16 pi_len;
-};
-
-#pragma pack(pop)
-/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
-
-/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
-/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
-#pragma pack(push, 1)
-/* Parameters to VMCALL_IO_CONTROLVM_ADDR interface */
-struct vmcall_io_controlvm_addr_params {
-	    /* The Guest-relative physical address of the ControlVm channel.
-	    * This VMCall fills this in with the appropriate address. */
-	u64 address;	/* contents provided by this VMCALL (OUT) */
-	    /* the size of the ControlVm channel in bytes This VMCall fills this
-	    * in with the appropriate address. */
-	u32 channel_bytes;	/* contents provided by this VMCALL (OUT) */
-	u8 unused[4];		/* Unused Bytes in the 64-Bit Aligned Struct */
-};
-
-#pragma pack(pop)
-/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
-
-/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
-/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
-#pragma pack(push, 1)
-/* Parameters to VMCALL_IO_DIAG_ADDR interface */
-struct vmcall_io_diag_addr_params {
-	    /* The Guest-relative physical address of the diagnostic channel.
-	    * This VMCall fills this in with the appropriate address. */
-	u64 address;	/* contents provided by this VMCALL (OUT) */
-};
-
-#pragma pack(pop)
-/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
-
-/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
-/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
-#pragma pack(push, 1)
-/* Parameters to VMCALL_IO_VISORSERIAL_ADDR interface */
-struct vmcall_io_visorserial_addr_params {
-	    /* The Guest-relative physical address of the serial console
-	    * channel.  This VMCall fills this in with the appropriate
-	    * address. */
-	u64 address;	/* contents provided by this VMCALL (OUT) */
-};
-
-#pragma pack(pop)
-/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
-
-/* Parameters to VMCALL_CHANNEL_MISMATCH interface */
-struct vmcall_channel_version_mismatch_params {
-	u8 chname[32];	/* Null terminated string giving name of channel
-				 * (IN) */
-	u8 item_name[32];	/* Null terminated string giving name of
-				 * mismatched item (IN) */
-	u32 line_no;		/* line# where invoked. (IN) */
-	u8 file_name[36];	/* source code where invoked - Null terminated
-				 * string (IN) */
-};
-
-#endif /* __IOMONINTF_H__ */
diff --git a/drivers/staging/unisys/visorbus/iovmcall_gnuc.h b/drivers/staging/unisys/visorbus/iovmcall_gnuc.h
new file mode 100644
index 0000000..57dd93e
--- /dev/null
+++ b/drivers/staging/unisys/visorbus/iovmcall_gnuc.h
@@ -0,0 +1,49 @@
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ */
+
+/* Linux GCC Version (32-bit and 64-bit) */
+static inline unsigned long
+__unisys_vmcall_gnuc(unsigned long tuple, unsigned long reg_ebx,
+		     unsigned long reg_ecx)
+{
+	unsigned long result = 0;
+	unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
+
+	cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
+	if (!(cpuid_ecx & 0x80000000))
+		return -1;
+
+	__asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
+		"a"(tuple), "b"(reg_ebx), "c"(reg_ecx));
+	return result;
+}
+
+static inline unsigned long
+__unisys_extended_vmcall_gnuc(unsigned long long tuple,
+			      unsigned long long reg_ebx,
+			      unsigned long long reg_ecx,
+			      unsigned long long reg_edx)
+{
+	unsigned long result = 0;
+	unsigned int cpuid_eax, cpuid_ebx, cpuid_ecx, cpuid_edx;
+
+	cpuid(0x00000001, &cpuid_eax, &cpuid_ebx, &cpuid_ecx, &cpuid_edx);
+	if (!(cpuid_ecx & 0x80000000))
+		return -1;
+
+	__asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
+		"a"(tuple), "b"(reg_ebx), "c"(reg_ecx), "d"(reg_edx));
+	return result;
+}
diff --git a/drivers/staging/unisys/visorbus/vbusdeviceinfo.h b/drivers/staging/unisys/visorbus/vbusdeviceinfo.h
new file mode 100644
index 0000000..9b6d3e6
--- /dev/null
+++ b/drivers/staging/unisys/visorbus/vbusdeviceinfo.h
@@ -0,0 +1,213 @@
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ */
+
+#ifndef __VBUSDEVICEINFO_H__
+#define __VBUSDEVICEINFO_H__
+
+#include <linux/types.h>
+
+#pragma pack(push, 1)		/* both GCC and VC now allow this pragma */
+
+/* An array of this struct is present in the channel area for each vbus.
+ * (See vbuschannel.h.)
+ * It is filled in by the client side to provide info about the device
+ * and driver from the client's perspective.
+ */
+struct ultra_vbus_deviceinfo {
+	u8 devtype[16];		/* short string identifying the device type */
+	u8 drvname[16];		/* driver .sys file name */
+	u8 infostrs[96];	/* sequence of tab-delimited id strings: */
+	/* <DRIVER_REV> <DRIVER_VERTAG> <DRIVER_COMPILETIME> */
+	u8 reserved[128];	/* pad size to 256 bytes */
+};
+
+#pragma pack(pop)
+
+/* Reads chars from the buffer at <src> for <srcmax> bytes, and writes to
+ * the buffer at <p>, which is <remain> bytes long, ensuring never to
+ * overflow the buffer at <p>, using the following rules:
+ * - printable characters are simply copied from the buffer at <src> to the
+ *   buffer at <p>
+ * - intervening streaks of non-printable characters in the buffer at <src>
+ *   are replaced with a single space in the buffer at <p>
+ * Note that we pay no attention to '\0'-termination.
+ * Returns the number of bytes written to <p>.
+ *
+ * Pass <p> == NULL and <remain> == 0 for this special behavior.  In this
+ * case, we simply return the number of bytes that WOULD HAVE been written
+ * to a buffer at <p>, had it been infinitely big.
+ */
+static inline int
+vbuschannel_sanitize_buffer(char *p, int remain, char *src, int srcmax)
+{
+	int chars = 0;
+	int nonprintable_streak = 0;
+
+	while (srcmax > 0) {
+		if ((*src >= ' ') && (*src < 0x7f)) {
+			if (nonprintable_streak) {
+				if (remain > 0) {
+					*p = ' ';
+					p++;
+					remain--;
+					chars++;
+				} else if (p == NULL) {
+					chars++;
+				}
+				nonprintable_streak = 0;
+			}
+			if (remain > 0) {
+				*p = *src;
+				p++;
+				remain--;
+				chars++;
+			} else if (p == NULL) {
+				chars++;
+			}
+		} else {
+			nonprintable_streak = 1;
+		}
+		src++;
+		srcmax--;
+	}
+	return chars;
+}
+
+#define VBUSCHANNEL_ADDACHAR(ch, p, remain, chars) \
+	do {					   \
+		if (remain <= 0)		   \
+			break;			   \
+		*p = ch;			   \
+		p++;  chars++;  remain--;	   \
+	} while (0)
+
+/* Converts the non-negative value at <num> to an ascii decimal string
+ * at <p>, writing at most <remain> bytes.  Note there is NO '\0' termination
+ * written to <p>.
+ *
+ * Returns the number of bytes written to <p>.
+ *
+ * Note that we create this function because we need to do this operation in
+ * an environment-independent way (since we are in a common header file).
+ */
+static inline int
+vbuschannel_itoa(char *p, int remain, int num)
+{
+	int digits = 0;
+	char s[32];
+	int i;
+
+	if (num == 0) {
+		/* '0' is a special case */
+		if (remain <= 0)
+			return 0;
+		*p = '0';
+		return 1;
+	}
+	/* form a backwards decimal ascii string in <s> */
+	while (num > 0) {
+		if (digits >= (int)sizeof(s))
+			return 0;
+		s[digits++] = (num % 10) + '0';
+		num = num / 10;
+	}
+	if (remain < digits) {
+		/* not enough room left at <p> to hold number, so fill with
+		 * '?' */
+		for (i = 0; i < remain; i++, p++)
+			*p = '?';
+		return remain;
+	}
+	/* plug in the decimal ascii string representing the number, by */
+	/* reversing the string we just built in <s> */
+	i = digits;
+	while (i > 0) {
+		i--;
+		*p = s[i];
+		p++;
+	}
+	return digits;
+}
+
+/* Reads <devInfo>, and converts its contents to a printable string at <p>,
+ * writing at most <remain> bytes.  Note there is NO '\0' termination
+ * written to <p>.
+ *
+ * Pass <devix> >= 0 if you want a device index presented.
+ *
+ * Returns the number of bytes written to <p>.
+ */
+static inline int
+vbuschannel_devinfo_to_string(struct ultra_vbus_deviceinfo *devinfo,
+			      char *p, int remain, int devix)
+{
+	char *psrc;
+	int nsrc, x, i, pad;
+	int chars = 0;
+
+	psrc = &devinfo->devtype[0];
+	nsrc = sizeof(devinfo->devtype);
+	if (vbuschannel_sanitize_buffer(NULL, 0, psrc, nsrc) <= 0)
+		return 0;
+
+	/* emit device index */
+	if (devix >= 0) {
+		VBUSCHANNEL_ADDACHAR('[', p, remain, chars);
+		x = vbuschannel_itoa(p, remain, devix);
+		p += x;
+		remain -= x;
+		chars += x;
+		VBUSCHANNEL_ADDACHAR(']', p, remain, chars);
+	} else {
+		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+	}
+
+	/* emit device type */
+	x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
+	p += x;
+	remain -= x;
+	chars += x;
+	pad = 15 - x;		/* pad device type to be exactly 15 chars */
+	for (i = 0; i < pad; i++)
+		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+	VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+
+	/* emit driver name */
+	psrc = &devinfo->drvname[0];
+	nsrc = sizeof(devinfo->drvname);
+	x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
+	p += x;
+	remain -= x;
+	chars += x;
+	pad = 15 - x;		/* pad driver name to be exactly 15 chars */
+	for (i = 0; i < pad; i++)
+		VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+	VBUSCHANNEL_ADDACHAR(' ', p, remain, chars);
+
+	/* emit strings */
+	psrc = &devinfo->infostrs[0];
+	nsrc = sizeof(devinfo->infostrs);
+	x = vbuschannel_sanitize_buffer(p, remain, psrc, nsrc);
+	p += x;
+	remain -= x;
+	chars += x;
+	VBUSCHANNEL_ADDACHAR('\n', p, remain, chars);
+
+	return chars;
+}
+
+#endif
diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h
new file mode 100644
index 0000000..dc09caf
--- /dev/null
+++ b/drivers/staging/unisys/visorbus/vmcallinterface.h
@@ -0,0 +1,161 @@
+/* Copyright (C) 2010 - 2013 UNISYS CORPORATION
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
+ * NON INFRINGEMENT.  See the GNU General Public License for more
+ * details.
+ */
+
+#ifndef __IOMONINTF_H__
+#define __IOMONINTF_H__
+
+/*
+* This file contains all structures needed to support the VMCALLs for IO
+* Virtualization.  The VMCALLs are provided by Monitor and used by IO code
+* running on IO Partitions.
+*/
+
+#ifdef __GNUC__
+#include "iovmcall_gnuc.h"
+#endif	/*  */
+#include "diagchannel.h"
+
+#ifdef VMCALL_IO_CONTROLVM_ADDR
+#undef VMCALL_IO_CONTROLVM_ADDR
+#endif	/*  */
+
+/* define subsystem number for AppOS, used in uislib driver  */
+#define MDS_APPOS 0x4000000000000000L	/* subsystem = 62 - AppOS */
+enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples  */
+	    /* Note: when a new VMCALL is added:
+	     * - the 1st 2 hex digits correspond to one of the
+	     *   VMCALL_MONITOR_INTERFACE types and
+	     * - the next 2 hex digits are the nth relative instance of within a
+	     *   type
+	     * E.G. for VMCALL_VIRTPART_RECYCLE_PART,
+	     * - the 0x02 identifies it as a VMCALL_VIRTPART type and
+	     * - the 0x01 identifies it as the 1st instance of a VMCALL_VIRTPART
+	     *   type of VMCALL
+	     */
+
+	VMCALL_IO_CONTROLVM_ADDR = 0x0501,	/* used by all Guests, not just
+						 * IO */
+	VMCALL_IO_DIAG_ADDR = 0x0508,
+	VMCALL_IO_VISORSERIAL_ADDR = 0x0509,
+	VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET = 0x0708, /* Allow caller to
+							  * query virtual time
+							  * offset */
+	VMCALL_CHANNEL_VERSION_MISMATCH = 0x0709,
+	VMCALL_POST_CODE_LOGEVENT = 0x070B,	/* LOGEVENT Post Code (RDX) with
+						 * specified subsystem mask (RCX
+						 * - monitor_subsystems.h) and
+						 * severity (RDX) */
+	VMCALL_GENERIC_SURRENDER_QUANTUM_FOREVER = 0x0802, /* Yield the
+							    * remainder & all
+							    * future quantums of
+							    * the caller */
+	VMCALL_MEASUREMENT_DO_NOTHING = 0x0901,
+	VMCALL_UPDATE_PHYSICAL_TIME = 0x0a02	/* Allow
+						 * ULTRA_SERVICE_CAPABILITY_TIME
+						 * capable guest to make
+						 * VMCALL */
+};
+
+#define VMCALL_SUCCESS 0
+#define VMCALL_SUCCESSFUL(result)	(result == 0)
+
+#ifdef __GNUC__
+#define unisys_vmcall(tuple, reg_ebx, reg_ecx) \
+	__unisys_vmcall_gnuc(tuple, reg_ebx, reg_ecx)
+#define unisys_extended_vmcall(tuple, reg_ebx, reg_ecx, reg_edx) \
+	__unisys_extended_vmcall_gnuc(tuple, reg_ebx, reg_ecx, reg_edx)
+#define ISSUE_IO_VMCALL(method, param, result) \
+	(result = unisys_vmcall(method, (param) & 0xFFFFFFFF,	\
+				(param) >> 32))
+#define ISSUE_IO_EXTENDED_VMCALL(method, param1, param2, param3) \
+	unisys_extended_vmcall(method, param1, param2, param3)
+
+    /* The following uses VMCALL_POST_CODE_LOGEVENT interface but is currently
+     * not used much */
+#define ISSUE_IO_VMCALL_POSTCODE_SEVERITY(postcode, severity)		\
+	ISSUE_IO_EXTENDED_VMCALL(VMCALL_POST_CODE_LOGEVENT, severity,	\
+				 MDS_APPOS, postcode)
+#endif
+
+/* Structures for IO VMCALLs */
+
+/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
+/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
+#pragma pack(push, 1)
+struct phys_info {
+	u64 pi_pfn;
+	u16 pi_off;
+	u16 pi_len;
+};
+
+#pragma pack(pop)
+/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
+
+/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
+/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
+#pragma pack(push, 1)
+/* Parameters to VMCALL_IO_CONTROLVM_ADDR interface */
+struct vmcall_io_controlvm_addr_params {
+	    /* The Guest-relative physical address of the ControlVm channel.
+	    * This VMCall fills this in with the appropriate address. */
+	u64 address;	/* contents provided by this VMCALL (OUT) */
+	    /* the size of the ControlVm channel in bytes This VMCall fills this
+	    * in with the appropriate address. */
+	u32 channel_bytes;	/* contents provided by this VMCALL (OUT) */
+	u8 unused[4];		/* Unused Bytes in the 64-Bit Aligned Struct */
+};
+
+#pragma pack(pop)
+/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
+
+/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
+/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
+#pragma pack(push, 1)
+/* Parameters to VMCALL_IO_DIAG_ADDR interface */
+struct vmcall_io_diag_addr_params {
+	    /* The Guest-relative physical address of the diagnostic channel.
+	    * This VMCall fills this in with the appropriate address. */
+	u64 address;	/* contents provided by this VMCALL (OUT) */
+};
+
+#pragma pack(pop)
+/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
+
+/* ///////////// BEGIN PRAGMA PACK PUSH 1 ///////////////////////// */
+/* ///////////// ONLY STRUCT TYPE SHOULD BE BELOW */
+#pragma pack(push, 1)
+/* Parameters to VMCALL_IO_VISORSERIAL_ADDR interface */
+struct vmcall_io_visorserial_addr_params {
+	    /* The Guest-relative physical address of the serial console
+	    * channel.  This VMCall fills this in with the appropriate
+	    * address. */
+	u64 address;	/* contents provided by this VMCALL (OUT) */
+};
+
+#pragma pack(pop)
+/* ///////////// END PRAGMA PACK PUSH 1 /////////////////////////// */
+
+/* Parameters to VMCALL_CHANNEL_MISMATCH interface */
+struct vmcall_channel_version_mismatch_params {
+	u8 chname[32];	/* Null terminated string giving name of channel
+				 * (IN) */
+	u8 item_name[32];	/* Null terminated string giving name of
+				 * mismatched item (IN) */
+	u32 line_no;		/* line# where invoked. (IN) */
+	u8 file_name[36];	/* source code where invoked - Null terminated
+				 * string (IN) */
+};
+
+#endif /* __IOMONINTF_H__ */
-- 
2.1.4



More information about the devel mailing list