aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/unisys
diff options
context:
space:
mode:
authorDavid Kershner <david.kershner@unisys.com>2017-03-28 09:35:01 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-03-29 09:17:04 +0200
commitbd801a0729c3e20f89f3297a5bbf9413339154a7 (patch)
tree55e908fe5df5fd7de7f2cecc75b5f6e2ee92aa51 /drivers/staging/unisys
parentstaging: unisys: visorbus: move unisys_vmcall into visorchipset (diff)
downloadlinux-dev-bd801a0729c3e20f89f3297a5bbf9413339154a7.tar.xz
linux-dev-bd801a0729c3e20f89f3297a5bbf9413339154a7.zip
staging: unisys: visorbus: Have unisys_vmcall return Linux error instead of VMCALL error
The function unisys_vmcall was returning VMCALL specific errors and the calling code was ignoring which error was actually returned. Instead we should be mapping the VMCALL error into a proper Linux error and then returning that, since we now have an error we know what to do with, we don't have to drop it but we can send it up the stack. Signed-off-by: David Kershner <david.kershner@unisys.com> Reviewed-by: Reviewed-by: Tim Sell <timothy.sell@unisys.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/unisys')
-rw-r--r--drivers/staging/unisys/visorbus/visorchipset.c33
-rw-r--r--drivers/staging/unisys/visorbus/vmcallinterface.h10
2 files changed, 32 insertions, 11 deletions
diff --git a/drivers/staging/unisys/visorbus/visorchipset.c b/drivers/staging/unisys/visorbus/visorchipset.c
index 9c48cfab0d2a..c370b6d72c94 100644
--- a/drivers/staging/unisys/visorbus/visorchipset.c
+++ b/drivers/staging/unisys/visorbus/visorchipset.c
@@ -1371,22 +1371,37 @@ static int unisys_vmcall(unsigned long tuple, unsigned long param)
__asm__ __volatile__(".byte 0x00f, 0x001, 0x0c1" : "=a"(result) :
"a"(tuple), "b"(reg_ebx), "c"(reg_ecx));
- return result;
+ if (result)
+ goto error;
+
+ return 0;
+
+error: /* Need to convert from VMCALL error codes to Linux */
+ switch (result) {
+ case VMCALL_RESULT_INVALID_PARAM:
+ return -EINVAL;
+ case VMCALL_RESULT_DATA_UNAVAILABLE:
+ return -ENODEV;
+ default:
+ return -EFAULT;
+ }
}
static unsigned int
issue_vmcall_io_controlvm_addr(u64 *control_addr, u32 *control_bytes)
{
struct vmcall_io_controlvm_addr_params params;
- int result = VMCALL_SUCCESS;
+ int err;
u64 physaddr;
physaddr = virt_to_phys(&params);
- result = unisys_vmcall(VMCALL_CONTROLVM_ADDR, physaddr);
- if (VMCALL_SUCCESSFUL(result)) {
- *control_addr = params.address;
- *control_bytes = params.channel_bytes;
- }
- return result;
+ err = unisys_vmcall(VMCALL_CONTROLVM_ADDR, physaddr);
+ if (err)
+ return err;
+
+ *control_addr = params.address;
+ *control_bytes = params.channel_bytes;
+
+ return 0;
}
static u64 controlvm_get_channel_address(void)
@@ -1394,7 +1409,7 @@ static u64 controlvm_get_channel_address(void)
u64 addr = 0;
u32 size = 0;
- if (!VMCALL_SUCCESSFUL(issue_vmcall_io_controlvm_addr(&addr, &size)))
+ if (issue_vmcall_io_controlvm_addr(&addr, &size))
return 0;
return addr;
diff --git a/drivers/staging/unisys/visorbus/vmcallinterface.h b/drivers/staging/unisys/visorbus/vmcallinterface.h
index 1b3650585173..1440cc8caf4c 100644
--- a/drivers/staging/unisys/visorbus/vmcallinterface.h
+++ b/drivers/staging/unisys/visorbus/vmcallinterface.h
@@ -62,8 +62,14 @@ enum vmcall_monitor_interface_method_tuple { /* VMCALL identification tuples */
VMCALL_UPDATE_PHYSICAL_TIME = 0x0a02
};
-#define VMCALL_SUCCESS 0
-#define VMCALL_SUCCESSFUL(result) (result == 0)
+enum vmcall_result {
+ VMCALL_RESULT_SUCCESS = 0,
+ VMCALL_RESULT_INVALID_PARAM = 1,
+ VMCALL_RESULT_DATA_UNAVAILABLE = 2,
+ VMCALL_RESULT_FAILURE_UNAVAILABLE = 3,
+ VMCALL_RESULT_DEVICE_ERROR = 4,
+ VMCALL_RESULT_DEVICE_NOT_READY = 5
+};
#define unisys_extended_vmcall(tuple, reg_ebx, reg_ecx, reg_edx) \
__unisys_extended_vmcall_gnuc(tuple, reg_ebx, reg_ecx, reg_edx)