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(¶ms); - 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)